mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
Every space in its place! (tm)
(whitespace clean up)
This commit is contained in:
parent
ded7a697d9
commit
7a18f0818c
@ -144,7 +144,7 @@ public class IkConstraint implements Updatable {
|
|||||||
if (u) {
|
if (u) {
|
||||||
l2 *= psx;
|
l2 *= psx;
|
||||||
var cos:Number = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2);
|
var cos:Number = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2);
|
||||||
if (cos < -1)
|
if (cos < -1)
|
||||||
cos = -1;
|
cos = -1;
|
||||||
else if (cos > 1) cos = 1;
|
else if (cos > 1) cos = 1;
|
||||||
a2 = Math.acos(cos) * bendDir;
|
a2 = Math.acos(cos) * bendDir;
|
||||||
|
|||||||
@ -173,7 +173,7 @@ public class PathConstraint implements Updatable {
|
|||||||
}
|
}
|
||||||
this._world.length = 8;
|
this._world.length = 8;
|
||||||
world = this._world;
|
world = this._world;
|
||||||
var o:int, curve:int;
|
var o:int, curve:int;
|
||||||
for (i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) {
|
for (i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) {
|
||||||
var space:Number = spaces[i];
|
var space:Number = spaces[i];
|
||||||
position += space;
|
position += space;
|
||||||
|
|||||||
@ -277,7 +277,7 @@ public class Skeleton {
|
|||||||
|
|
||||||
public function setSlotsToSetupPose () : void {
|
public function setSlotsToSetupPose () : void {
|
||||||
var i:int = 0;
|
var i:int = 0;
|
||||||
for each (var slot:Slot in slots) {
|
for each (var slot:Slot in slots) {
|
||||||
drawOrder[i++] = slot;
|
drawOrder[i++] = slot;
|
||||||
slot.setToSetupPose();
|
slot.setToSetupPose();
|
||||||
}
|
}
|
||||||
@ -353,8 +353,8 @@ public class Skeleton {
|
|||||||
return _skin == null ? null : _skin._name;
|
return _skin == null ? null : _skin._name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the skin used to look up attachments before looking in the {@link SkeletonData#getDefaultSkin() default skin}.
|
/** Sets the skin used to look up attachments before looking in the {@link SkeletonData#getDefaultSkin() default skin}.
|
||||||
* Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was
|
* Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was
|
||||||
* no old skin, each slot's setup mode attachment is attached from the new skin.
|
* no old skin, each slot's setup mode attachment is attached from the new skin.
|
||||||
* @param newSkin May be null. */
|
* @param newSkin May be null. */
|
||||||
public function set skin (newSkin:Skin) : void {
|
public function set skin (newSkin:Skin) : void {
|
||||||
|
|||||||
@ -366,14 +366,14 @@ public class SkeletonJson {
|
|||||||
var bones:Vector.<int> = new Vector.<int>(verticesLength * 3);
|
var bones:Vector.<int> = new Vector.<int>(verticesLength * 3);
|
||||||
bones.length = 0;
|
bones.length = 0;
|
||||||
for (i = 0, n = vertices.length; i < n;) {
|
for (i = 0, n = vertices.length; i < n;) {
|
||||||
var boneCount:int = int(vertices[i++]);
|
var boneCount:int = int(vertices[i++]);
|
||||||
bones.push(boneCount);
|
bones.push(boneCount);
|
||||||
for (var nn:int = i + boneCount * 4; i < nn; i+=4) {
|
for (var nn:int = i + boneCount * 4; i < nn; i+=4) {
|
||||||
bones.push(int(vertices[i]));
|
bones.push(int(vertices[i]));
|
||||||
weights.push(vertices[i + 1] * scale);
|
weights.push(vertices[i + 1] * scale);
|
||||||
weights.push(vertices[i + 2] * scale);
|
weights.push(vertices[i + 2] * scale);
|
||||||
weights.push(vertices[i + 3]);
|
weights.push(vertices[i + 3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
attachment.bones = bones;
|
attachment.bones = bones;
|
||||||
attachment.vertices = weights;
|
attachment.vertices = weights;
|
||||||
|
|||||||
@ -121,7 +121,7 @@ public class Animation {
|
|||||||
}
|
}
|
||||||
return 0; // Can't happen.
|
return 0; // Can't happen.
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function linearSearch (values:Vector.<Number>, target:Number, step:int) : int {
|
static public function linearSearch (values:Vector.<Number>, target:Number, step:int) : int {
|
||||||
for (var i:int = 0, last:int = values.length - step; i <= last; i += step)
|
for (var i:int = 0, last:int = values.length - step; i <= last; i += step)
|
||||||
if (values[i] > target)
|
if (values[i] > target)
|
||||||
|
|||||||
@ -53,7 +53,7 @@ public class AnimationState {
|
|||||||
for (var i:int = 0; i < _tracks.length; i++) {
|
for (var i:int = 0; i < _tracks.length; i++) {
|
||||||
var current:TrackEntry = _tracks[i];
|
var current:TrackEntry = _tracks[i];
|
||||||
if (!current) continue;
|
if (!current) continue;
|
||||||
|
|
||||||
current.time += delta * current.timeScale;
|
current.time += delta * current.timeScale;
|
||||||
if (current.previous) {
|
if (current.previous) {
|
||||||
var previousDelta:Number = delta * current.previous.timeScale;
|
var previousDelta:Number = delta * current.previous.timeScale;
|
||||||
@ -76,15 +76,15 @@ public class AnimationState {
|
|||||||
for (var i:int = 0; i < _tracks.length; i++) {
|
for (var i:int = 0; i < _tracks.length; i++) {
|
||||||
var current:TrackEntry = _tracks[i];
|
var current:TrackEntry = _tracks[i];
|
||||||
if (!current) continue;
|
if (!current) continue;
|
||||||
|
|
||||||
_events.length = 0;
|
_events.length = 0;
|
||||||
|
|
||||||
var time:Number = current.time;
|
var time:Number = current.time;
|
||||||
var lastTime:Number = current.lastTime;
|
var lastTime:Number = current.lastTime;
|
||||||
var endTime:Number = current.endTime;
|
var endTime:Number = current.endTime;
|
||||||
var loop:Boolean = current.loop;
|
var loop:Boolean = current.loop;
|
||||||
if (!loop && time > endTime) time = endTime;
|
if (!loop && time > endTime) time = endTime;
|
||||||
|
|
||||||
var previous:TrackEntry = current.previous;
|
var previous:TrackEntry = current.previous;
|
||||||
if (!previous) {
|
if (!previous) {
|
||||||
if (current.mix == 1)
|
if (current.mix == 1)
|
||||||
@ -95,7 +95,7 @@ public class AnimationState {
|
|||||||
var previousTime:Number = previous.time;
|
var previousTime:Number = previous.time;
|
||||||
if (!previous.loop && previousTime > previous.endTime) previousTime = previous.endTime;
|
if (!previous.loop && previousTime > previous.endTime) previousTime = previous.endTime;
|
||||||
previous.animation.apply(skeleton, previousTime, previousTime, previous.loop, null);
|
previous.animation.apply(skeleton, previousTime, previousTime, previous.loop, null);
|
||||||
|
|
||||||
var alpha:Number = current.mixTime / current.mixDuration * current.mix;
|
var alpha:Number = current.mixTime / current.mixDuration * current.mix;
|
||||||
if (alpha >= 1) {
|
if (alpha >= 1) {
|
||||||
alpha = 1;
|
alpha = 1;
|
||||||
@ -103,7 +103,7 @@ public class AnimationState {
|
|||||||
}
|
}
|
||||||
current.animation.mix(skeleton, current.lastTime, time, loop, _events, alpha);
|
current.animation.mix(skeleton, current.lastTime, time, loop, _events, alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
for each (var event:Event in _events) {
|
for each (var event:Event in _events) {
|
||||||
if (current.onEvent != null) current.onEvent(i, event);
|
if (current.onEvent != null) current.onEvent(i, event);
|
||||||
onEvent.invoke(i, event);
|
onEvent.invoke(i, event);
|
||||||
@ -123,9 +123,9 @@ public class AnimationState {
|
|||||||
public function clearTracks () : void {
|
public function clearTracks () : void {
|
||||||
for (var i:int = 0, n:int = _tracks.length; i < n; i++)
|
for (var i:int = 0, n:int = _tracks.length; i < n; i++)
|
||||||
clearTrack(i);
|
clearTrack(i);
|
||||||
_tracks.length = 0;
|
_tracks.length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function clearTrack (trackIndex:int) : void {
|
public function clearTrack (trackIndex:int) : void {
|
||||||
if (trackIndex >= _tracks.length) return;
|
if (trackIndex >= _tracks.length) return;
|
||||||
var current:TrackEntry = _tracks[trackIndex];
|
var current:TrackEntry = _tracks[trackIndex];
|
||||||
@ -136,14 +136,14 @@ public class AnimationState {
|
|||||||
|
|
||||||
_tracks[trackIndex] = null;
|
_tracks[trackIndex] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function expandToIndex (index:int) : TrackEntry {
|
private function expandToIndex (index:int) : TrackEntry {
|
||||||
if (index < _tracks.length) return _tracks[index];
|
if (index < _tracks.length) return _tracks[index];
|
||||||
while (index >= _tracks.length)
|
while (index >= _tracks.length)
|
||||||
_tracks[_tracks.length] = null;
|
_tracks[_tracks.length] = null;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function setCurrent (index:int, entry:TrackEntry) : void {
|
private function setCurrent (index:int, entry:TrackEntry) : void {
|
||||||
var current:TrackEntry = expandToIndex(index);
|
var current:TrackEntry = expandToIndex(index);
|
||||||
if (current) {
|
if (current) {
|
||||||
@ -164,19 +164,19 @@ public class AnimationState {
|
|||||||
entry.previous = current;
|
entry.previous = current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_tracks[index] = entry;
|
_tracks[index] = entry;
|
||||||
|
|
||||||
if (entry.onStart != null) entry.onStart(index);
|
if (entry.onStart != null) entry.onStart(index);
|
||||||
onStart.invoke(index);
|
onStart.invoke(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setAnimationByName (trackIndex:int, animationName:String, loop:Boolean) : TrackEntry {
|
public function setAnimationByName (trackIndex:int, animationName:String, loop:Boolean) : TrackEntry {
|
||||||
var animation:Animation = _data._skeletonData.findAnimation(animationName);
|
var animation:Animation = _data._skeletonData.findAnimation(animationName);
|
||||||
if (!animation) throw new ArgumentError("Animation not found: " + animationName);
|
if (!animation) throw new ArgumentError("Animation not found: " + animationName);
|
||||||
return setAnimation(trackIndex, animation, loop);
|
return setAnimation(trackIndex, animation, loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set the current animation. Any queued animations are cleared. */
|
/** Set the current animation. Any queued animations are cleared. */
|
||||||
public function setAnimation (trackIndex:int, animation:Animation, loop:Boolean) : TrackEntry {
|
public function setAnimation (trackIndex:int, animation:Animation, loop:Boolean) : TrackEntry {
|
||||||
var entry:TrackEntry = new TrackEntry();
|
var entry:TrackEntry = new TrackEntry();
|
||||||
@ -186,13 +186,13 @@ public class AnimationState {
|
|||||||
setCurrent(trackIndex, entry);
|
setCurrent(trackIndex, entry);
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addAnimationByName (trackIndex:int, animationName:String, loop:Boolean, delay:Number) : TrackEntry {
|
public function addAnimationByName (trackIndex:int, animationName:String, loop:Boolean, delay:Number) : TrackEntry {
|
||||||
var animation:Animation = _data._skeletonData.findAnimation(animationName);
|
var animation:Animation = _data._skeletonData.findAnimation(animationName);
|
||||||
if (!animation) throw new ArgumentError("Animation not found: " + animationName);
|
if (!animation) throw new ArgumentError("Animation not found: " + animationName);
|
||||||
return addAnimation(trackIndex, animation, loop, delay);
|
return addAnimation(trackIndex, animation, loop, delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds an animation to be played delay seconds after the current or last queued animation.
|
/** Adds an animation to be played delay seconds after the current or last queued animation.
|
||||||
* @param delay May be <= 0 to use duration of previous animation minus any mix duration plus the negative delay. */
|
* @param delay May be <= 0 to use duration of previous animation minus any mix duration plus the negative delay. */
|
||||||
public function addAnimation (trackIndex:int, animation:Animation, loop:Boolean, delay:Number) : TrackEntry {
|
public function addAnimation (trackIndex:int, animation:Animation, loop:Boolean, delay:Number) : TrackEntry {
|
||||||
@ -200,7 +200,7 @@ public class AnimationState {
|
|||||||
entry.animation = animation;
|
entry.animation = animation;
|
||||||
entry.loop = loop;
|
entry.loop = loop;
|
||||||
entry.endTime = animation.duration;
|
entry.endTime = animation.duration;
|
||||||
|
|
||||||
var last:TrackEntry = expandToIndex(trackIndex);
|
var last:TrackEntry = expandToIndex(trackIndex);
|
||||||
if (last) {
|
if (last) {
|
||||||
while (last.next)
|
while (last.next)
|
||||||
@ -208,7 +208,7 @@ public class AnimationState {
|
|||||||
last.next = entry;
|
last.next = entry;
|
||||||
} else
|
} else
|
||||||
_tracks[trackIndex] = entry;
|
_tracks[trackIndex] = entry;
|
||||||
|
|
||||||
if (delay <= 0) {
|
if (delay <= 0) {
|
||||||
if (last)
|
if (last)
|
||||||
delay += last.endTime - _data.getMix(last.animation, animation);
|
delay += last.endTime - _data.getMix(last.animation, animation);
|
||||||
@ -216,10 +216,10 @@ public class AnimationState {
|
|||||||
delay = 0;
|
delay = 0;
|
||||||
}
|
}
|
||||||
entry.delay = delay;
|
entry.delay = delay;
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** May be null. */
|
/** May be null. */
|
||||||
public function getCurrent (trackIndex:int) : TrackEntry {
|
public function getCurrent (trackIndex:int) : TrackEntry {
|
||||||
if (trackIndex >= _tracks.length) return null;
|
if (trackIndex >= _tracks.length) return null;
|
||||||
|
|||||||
@ -37,7 +37,7 @@ import spine.Skeleton;
|
|||||||
public class CurveTimeline implements Timeline {
|
public class CurveTimeline implements Timeline {
|
||||||
static private const LINEAR:Number = 0;
|
static private const LINEAR:Number = 0;
|
||||||
static private const STEPPED:Number = 1;
|
static private const STEPPED:Number = 1;
|
||||||
static private const BEZIER:Number = 2;
|
static private const BEZIER:Number = 2;
|
||||||
static private const BEZIER_SIZE:int = 10 * 2 - 1;
|
static private const BEZIER_SIZE:int = 10 * 2 - 1;
|
||||||
|
|
||||||
private var curves:Vector.<Number>; // type, x, y, ...
|
private var curves:Vector.<Number>; // type, x, y, ...
|
||||||
|
|||||||
@ -84,8 +84,8 @@ public class DeformTimeline extends CurveTimeline {
|
|||||||
var frame:int = Animation.binarySearch1(frames, time);
|
var frame:int = Animation.binarySearch1(frames, time);
|
||||||
var prevVertices:Vector.<Number> = frameVertices[int(frame - 1)];
|
var prevVertices:Vector.<Number> = frameVertices[int(frame - 1)];
|
||||||
var nextVertices:Vector.<Number> = frameVertices[frame];
|
var nextVertices:Vector.<Number> = frameVertices[frame];
|
||||||
var frameTime:Number = frames[frame];
|
var frameTime:Number = frames[frame];
|
||||||
var percent:Number = getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime));
|
var percent:Number = getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime));
|
||||||
|
|
||||||
var prev:Number;
|
var prev:Number;
|
||||||
if (alpha < 1) {
|
if (alpha < 1) {
|
||||||
|
|||||||
@ -70,7 +70,7 @@ public class DrawOrderTimeline implements Timeline {
|
|||||||
for each (var slot:Slot in slots)
|
for each (var slot:Slot in slots)
|
||||||
drawOrder[i++] = slot;
|
drawOrder[i++] = slot;
|
||||||
} else {
|
} else {
|
||||||
for each (var setupIndex:int in drawOrderToSetupIndex)
|
for each (var setupIndex:int in drawOrderToSetupIndex)
|
||||||
drawOrder[i++] = slots[setupIndex];
|
drawOrder[i++] = slots[setupIndex];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,14 +54,14 @@ public class EventTimeline implements Timeline {
|
|||||||
/** Fires events for frames > lastTime and <= time. */
|
/** Fires events for frames > lastTime and <= time. */
|
||||||
public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
|
public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
|
||||||
if (!firedEvents) return;
|
if (!firedEvents) return;
|
||||||
|
|
||||||
if (lastTime > time) { // Fire events after last time for looped animations.
|
if (lastTime > time) { // Fire events after last time for looped animations.
|
||||||
apply(skeleton, lastTime, int.MAX_VALUE, firedEvents, alpha);
|
apply(skeleton, lastTime, int.MAX_VALUE, firedEvents, alpha);
|
||||||
lastTime = -1;
|
lastTime = -1;
|
||||||
} else if (lastTime >= frames[int(frameCount - 1)]) // Last time is after last frame.
|
} else if (lastTime >= frames[int(frameCount - 1)]) // Last time is after last frame.
|
||||||
return;
|
return;
|
||||||
if (time < frames[0]) return; // Time is before first frame.
|
if (time < frames[0]) return; // Time is before first frame.
|
||||||
|
|
||||||
var frame:int;
|
var frame:int;
|
||||||
if (lastTime < frames[0])
|
if (lastTime < frames[0])
|
||||||
frame = 0;
|
frame = 0;
|
||||||
|
|||||||
@ -31,14 +31,14 @@
|
|||||||
package spine.animation {
|
package spine.animation {
|
||||||
public class Listeners {
|
public class Listeners {
|
||||||
private var _listeners:Vector.<Function> = new Vector.<Function>();
|
private var _listeners:Vector.<Function> = new Vector.<Function>();
|
||||||
|
|
||||||
public function Listeners () {
|
public function Listeners () {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get listeners () : Vector.<Function> {
|
public function get listeners () : Vector.<Function> {
|
||||||
return _listeners;
|
return _listeners;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function add (listener:Function) : void {
|
public function add (listener:Function) : void {
|
||||||
if (listener == null)
|
if (listener == null)
|
||||||
throw new ArgumentError("listener cannot be null.");
|
throw new ArgumentError("listener cannot be null.");
|
||||||
|
|||||||
@ -39,13 +39,13 @@ public class PathConstraintMixTimeline extends CurveTimeline {
|
|||||||
static internal const ROTATE:int = 1, TRANSLATE:int = 2;
|
static internal const ROTATE:int = 1, TRANSLATE:int = 2;
|
||||||
|
|
||||||
public var pathConstraintIndex:int;
|
public var pathConstraintIndex:int;
|
||||||
|
|
||||||
public var frames:Vector.<Number>; // time, rotate mix, translate mix, ...
|
public var frames:Vector.<Number>; // time, rotate mix, translate mix, ...
|
||||||
|
|
||||||
public function PathConstraintMixTimeline (frameCount:int) {
|
public function PathConstraintMixTimeline (frameCount:int) {
|
||||||
super(frameCount);
|
super(frameCount);
|
||||||
frames = new Vector.<Number>(frameCount * ENTRIES, true);
|
frames = new Vector.<Number>(frameCount * ENTRIES, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the time and mixes of the specified keyframe. */
|
/** Sets the time and mixes of the specified keyframe. */
|
||||||
public function setFrame (frameIndex:int, time:Number, rotateMix:Number, translateMix:Number) : void {
|
public function setFrame (frameIndex:int, time:Number, rotateMix:Number, translateMix:Number) : void {
|
||||||
@ -55,7 +55,7 @@ public class PathConstraintMixTimeline extends CurveTimeline {
|
|||||||
frames[frameIndex + TRANSLATE] = translateMix;
|
frames[frameIndex + TRANSLATE] = translateMix;
|
||||||
}
|
}
|
||||||
|
|
||||||
override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
|
override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
|
||||||
if (time < frames[0]) return; // Time is before first frame.
|
if (time < frames[0]) return; // Time is before first frame.
|
||||||
|
|
||||||
var constraint:PathConstraint = skeleton.pathConstraints[pathConstraintIndex];
|
var constraint:PathConstraint = skeleton.pathConstraints[pathConstraintIndex];
|
||||||
|
|||||||
@ -32,7 +32,7 @@ package spine.animation {
|
|||||||
import spine.PathConstraint;
|
import spine.PathConstraint;
|
||||||
import spine.Event;
|
import spine.Event;
|
||||||
import spine.Skeleton;
|
import spine.Skeleton;
|
||||||
|
|
||||||
public class PathConstraintPositionTimeline extends CurveTimeline {
|
public class PathConstraintPositionTimeline extends CurveTimeline {
|
||||||
static public const ENTRIES:int = 2;
|
static public const ENTRIES:int = 2;
|
||||||
static internal const PREV_TIME:int = -2, PREV_VALUE:int = -1;
|
static internal const PREV_TIME:int = -2, PREV_VALUE:int = -1;
|
||||||
@ -54,7 +54,7 @@ public class PathConstraintPositionTimeline extends CurveTimeline {
|
|||||||
frames[frameIndex + VALUE] = value;
|
frames[frameIndex + VALUE] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
|
override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
|
||||||
if (time < frames[0]) return; // Time is before first frame.
|
if (time < frames[0]) return; // Time is before first frame.
|
||||||
|
|
||||||
var constraint:PathConstraint = skeleton.pathConstraints[pathConstraintIndex];
|
var constraint:PathConstraint = skeleton.pathConstraints[pathConstraintIndex];
|
||||||
|
|||||||
@ -38,7 +38,7 @@ public class PathConstraintSpacingTimeline extends PathConstraintPositionTimelin
|
|||||||
super(frameCount);
|
super(frameCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
|
override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number) : void {
|
||||||
if (time < frames[0]) return; // Time is before first frame.
|
if (time < frames[0]) return; // Time is before first frame.
|
||||||
|
|
||||||
var constraint:PathConstraint = skeleton.pathConstraints[pathConstraintIndex];
|
var constraint:PathConstraint = skeleton.pathConstraints[pathConstraintIndex];
|
||||||
|
|||||||
@ -58,7 +58,7 @@ public class RotateTimeline extends CurveTimeline {
|
|||||||
return; // Time is before first frame.
|
return; // Time is before first frame.
|
||||||
|
|
||||||
var bone:Bone = skeleton.bones[boneIndex];
|
var bone:Bone = skeleton.bones[boneIndex];
|
||||||
|
|
||||||
if (time >= frames[int(frames.length - 2)]) { // Time is after last frame.
|
if (time >= frames[int(frames.length - 2)]) { // Time is after last frame.
|
||||||
var amount:Number = bone.data.rotation + frames[int(frames.length + PREV_ROTATION)] - bone.rotation;
|
var amount:Number = bone.data.rotation + frames[int(frames.length + PREV_ROTATION)] - bone.rotation;
|
||||||
while (amount > 180)
|
while (amount > 180)
|
||||||
@ -72,7 +72,7 @@ public class RotateTimeline extends CurveTimeline {
|
|||||||
// Interpolate between the previous frame and the current frame.
|
// Interpolate between the previous frame and the current frame.
|
||||||
var frame:int = Animation.binarySearch(frames, time, ENTRIES);
|
var frame:int = Animation.binarySearch(frames, time, ENTRIES);
|
||||||
var prevRotation:Number = frames[int(frame + PREV_ROTATION)];
|
var prevRotation:Number = frames[int(frame + PREV_ROTATION)];
|
||||||
var frameTime:Number = frames[frame];
|
var frameTime:Number = frames[frame];
|
||||||
var percent:Number = getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
|
var percent:Number = getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
|
||||||
|
|
||||||
amount = frames[int(frame + ROTATION)] - prevRotation;
|
amount = frames[int(frame + ROTATION)] - prevRotation;
|
||||||
|
|||||||
@ -38,10 +38,10 @@ public class TrackEntry {
|
|||||||
public var delay:Number, time:Number = 0, lastTime:Number = -1, endTime:Number, timeScale:Number = 1;
|
public var delay:Number, time:Number = 0, lastTime:Number = -1, endTime:Number, timeScale:Number = 1;
|
||||||
internal var mixTime:Number, mixDuration:Number, mix:Number = 1;
|
internal var mixTime:Number, mixDuration:Number, mix:Number = 1;
|
||||||
public var onStart:Function, onEnd:Function, onComplete:Function, onEvent:Function;
|
public var onStart:Function, onEnd:Function, onComplete:Function, onEvent:Function;
|
||||||
|
|
||||||
public function TrackEntry () {
|
public function TrackEntry () {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toString () : String {
|
public function toString () : String {
|
||||||
return animation == null ? "<none>" : animation.name;
|
return animation == null ? "<none>" : animation.name;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,7 +45,7 @@ public class TransformConstraintTimeline extends CurveTimeline {
|
|||||||
super(frameCount);
|
super(frameCount);
|
||||||
frames = new Vector.<Number>(frameCount * ENTRIES, true);
|
frames = new Vector.<Number>(frameCount * ENTRIES, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the time and mixes of the specified keyframe. */
|
/** Sets the time and mixes of the specified keyframe. */
|
||||||
public function setFrame (frameIndex:int, time:Number, rotateMix:Number, translateMix:Number, scaleMix:Number, shearMix:Number) : void {
|
public function setFrame (frameIndex:int, time:Number, rotateMix:Number, translateMix:Number, scaleMix:Number, shearMix:Number) : void {
|
||||||
frameIndex *= ENTRIES;
|
frameIndex *= ENTRIES;
|
||||||
|
|||||||
@ -40,7 +40,7 @@ public class FlashTextureLoader implements TextureLoader {
|
|||||||
public var bitmapDatas:Object = {};
|
public var bitmapDatas:Object = {};
|
||||||
public var singleBitmapData:BitmapData;
|
public var singleBitmapData:BitmapData;
|
||||||
|
|
||||||
/** @param bitmaps A Bitmap or BitmapData for an atlas that has only one page, or for a multi page atlas an object where the
|
/** @param bitmaps A Bitmap or BitmapData for an atlas that has only one page, or for a multi page atlas an object where the
|
||||||
* key is the image path and the value is the Bitmap or BitmapData. */
|
* key is the image path and the value is the Bitmap or BitmapData. */
|
||||||
public function FlashTextureLoader (bitmaps:Object) {
|
public function FlashTextureLoader (bitmaps:Object) {
|
||||||
if (bitmaps is BitmapData) {
|
if (bitmaps is BitmapData) {
|
||||||
|
|||||||
@ -67,7 +67,7 @@ struct spBone {
|
|||||||
a(0), b(0), worldX(0),
|
a(0), b(0), worldX(0),
|
||||||
c(0), d(0), worldY(0),
|
c(0), d(0), worldY(0),
|
||||||
worldSignX(0), worldSignY(0),
|
worldSignX(0), worldSignY(0),
|
||||||
|
|
||||||
sorted(0) {
|
sorted(0) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -42,10 +42,10 @@ struct spSkeleton;
|
|||||||
|
|
||||||
typedef struct spIkConstraint {
|
typedef struct spIkConstraint {
|
||||||
spIkConstraintData* const data;
|
spIkConstraintData* const data;
|
||||||
|
|
||||||
int bonesCount;
|
int bonesCount;
|
||||||
spBone** bones;
|
spBone** bones;
|
||||||
|
|
||||||
spBone* target;
|
spBone* target;
|
||||||
int bendDirection;
|
int bendDirection;
|
||||||
float mix;
|
float mix;
|
||||||
|
|||||||
@ -39,10 +39,10 @@ extern "C" {
|
|||||||
|
|
||||||
typedef struct spIkConstraintData {
|
typedef struct spIkConstraintData {
|
||||||
const char* const name;
|
const char* const name;
|
||||||
|
|
||||||
int bonesCount;
|
int bonesCount;
|
||||||
spBoneData** bones;
|
spBoneData** bones;
|
||||||
|
|
||||||
spBoneData* target;
|
spBoneData* target;
|
||||||
int bendDirection;
|
int bendDirection;
|
||||||
float mix;
|
float mix;
|
||||||
|
|||||||
@ -463,7 +463,7 @@ void _spColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
|
|||||||
|
|
||||||
frameTime = self->frames[frame];
|
frameTime = self->frames[frame];
|
||||||
percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / COLOR_ENTRIES - 1,
|
percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / COLOR_ENTRIES - 1,
|
||||||
1 - (time - frameTime) / (self->frames[frame + COLOR_PREV_TIME] - frameTime));
|
1 - (time - frameTime) / (self->frames[frame + COLOR_PREV_TIME] - frameTime));
|
||||||
|
|
||||||
r += (self->frames[frame + COLOR_R] - r) * percent;
|
r += (self->frames[frame + COLOR_R] - r) * percent;
|
||||||
g += (self->frames[frame + COLOR_G] - g) * percent;
|
g += (self->frames[frame + COLOR_G] - g) * percent;
|
||||||
@ -918,7 +918,7 @@ static const int PATHCONSTRAINTPOSITION_PREV_VALUE = -1;
|
|||||||
static const int PATHCONSTRAINTPOSITION_VALUE = 1;
|
static const int PATHCONSTRAINTPOSITION_VALUE = 1;
|
||||||
|
|
||||||
void _spPathConstraintPositionTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
|
void _spPathConstraintPositionTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
|
||||||
spEvent** firedEvents, int* eventsCount, float alpha) {
|
spEvent** firedEvents, int* eventsCount, float alpha) {
|
||||||
int frame;
|
int frame;
|
||||||
float frameTime, percent, position;
|
float frameTime, percent, position;
|
||||||
spPathConstraint* constraint;
|
spPathConstraint* constraint;
|
||||||
@ -963,7 +963,7 @@ static const int PATHCONSTRAINTSPACING_PREV_VALUE = -1;
|
|||||||
static const int PATHCONSTRAINTSPACING_VALUE = 1;
|
static const int PATHCONSTRAINTSPACING_VALUE = 1;
|
||||||
|
|
||||||
void _spPathConstraintSpacingTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
|
void _spPathConstraintSpacingTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
|
||||||
spEvent** firedEvents, int* eventsCount, float alpha) {
|
spEvent** firedEvents, int* eventsCount, float alpha) {
|
||||||
int frame;
|
int frame;
|
||||||
float frameTime, percent, spacing;
|
float frameTime, percent, spacing;
|
||||||
spPathConstraint* constraint;
|
spPathConstraint* constraint;
|
||||||
|
|||||||
@ -202,7 +202,7 @@ spAtlas* spAtlas_create (const char* begin, int length, const char* dir, void* r
|
|||||||
switch (readTuple(&begin, end, tuple)) {
|
switch (readTuple(&begin, end, tuple)) {
|
||||||
case 0:
|
case 0:
|
||||||
return abortAtlas(self);
|
return abortAtlas(self);
|
||||||
case 2: /* size is only optional for an atlas packed with an old TexturePacker. */
|
case 2: /* size is only optional for an atlas packed with an old TexturePacker. */
|
||||||
page->width = toInt(tuple);
|
page->width = toInt(tuple);
|
||||||
page->height = toInt(tuple + 1);
|
page->height = toInt(tuple + 1);
|
||||||
if (!readTuple(&begin, end, tuple)) return abortAtlas(self);
|
if (!readTuple(&begin, end, tuple)) return abortAtlas(self);
|
||||||
|
|||||||
@ -126,7 +126,7 @@ void spPathConstraint_apply (spPathConstraint* self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
positions = spPathConstraint_computeWorldPositions(self, attachment, spacesCount, tangents,
|
positions = spPathConstraint_computeWorldPositions(self, attachment, spacesCount, tangents,
|
||||||
data->positionMode == SP_POSITION_MODE_PERCENT, spacingMode == SP_SPACING_MODE_PERCENT);
|
data->positionMode == SP_POSITION_MODE_PERCENT, spacingMode == SP_SPACING_MODE_PERCENT);
|
||||||
skeleton = self->target->bone->skeleton;
|
skeleton = self->target->bone->skeleton;
|
||||||
skeletonX = skeleton->x, skeletonY = skeleton->y;
|
skeletonX = skeleton->x, skeletonY = skeleton->y;
|
||||||
boneX = positions[0], boneY = positions[1], offsetRotation = self->data->offsetRotation;
|
boneX = positions[0], boneY = positions[1], offsetRotation = self->data->offsetRotation;
|
||||||
@ -192,7 +192,7 @@ static void _addAfterPosition (float p, float* temp, int i, float* out, int o) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void _addCurvePosition (float p, float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2,
|
static void _addCurvePosition (float p, float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2,
|
||||||
float* out, int o, int/*bool*/tangents) {
|
float* out, int o, int/*bool*/tangents) {
|
||||||
float tt, ttt, u, uu, uuu;
|
float tt, ttt, u, uu, uuu;
|
||||||
float ut, ut3, uut3, utt3;
|
float ut, ut3, uut3, utt3;
|
||||||
float x, y;
|
float x, y;
|
||||||
@ -283,7 +283,7 @@ float* spPathConstraint_computeWorldPositions(spPathConstraint* self, spPathAtta
|
|||||||
spPathAttachment_computeWorldVertices1(path, target, curve * 6 + 2, 8, world, 0);
|
spPathAttachment_computeWorldVertices1(path, target, curve * 6 + 2, 8, world, 0);
|
||||||
}
|
}
|
||||||
_addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o,
|
_addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o,
|
||||||
tangents || (i > 0 && space == 0));
|
tangents || (i > 0 && space == 0));
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -353,7 +353,7 @@ static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* r
|
|||||||
timeline->pathConstraintIndex = constraintIndex;
|
timeline->pathConstraintIndex = constraintIndex;
|
||||||
for (valueMap = timelineMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
|
for (valueMap = timelineMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
|
||||||
spPathConstraintMixTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0),
|
spPathConstraintMixTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0),
|
||||||
Json_getFloat(valueMap, "rotateMix", 1), Json_getFloat(valueMap, "translateMix", 1));
|
Json_getFloat(valueMap, "rotateMix", 1), Json_getFloat(valueMap, "translateMix", 1));
|
||||||
readCurve(valueMap, SUPER(timeline), frameIndex);
|
readCurve(valueMap, SUPER(timeline), frameIndex);
|
||||||
}
|
}
|
||||||
animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
|
animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
|
||||||
@ -576,14 +576,14 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
oldLocale = strdup(setlocale(LC_NUMERIC, NULL));
|
oldLocale = strdup(setlocale(LC_NUMERIC, NULL));
|
||||||
setlocale(LC_NUMERIC, "C");
|
setlocale(LC_NUMERIC, "C");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
root = Json_create(json);
|
root = Json_create(json);
|
||||||
|
|
||||||
#ifndef __ANDROID__
|
#ifndef __ANDROID__
|
||||||
setlocale(LC_NUMERIC, oldLocale);
|
setlocale(LC_NUMERIC, oldLocale);
|
||||||
free(oldLocale);
|
free(oldLocale);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!root) {
|
if (!root) {
|
||||||
_spSkeletonJson_setError(self, 0, "Invalid skeleton JSON: ", Json_getError());
|
_spSkeletonJson_setError(self, 0, "Invalid skeleton JSON: ", Json_getError());
|
||||||
return 0;
|
return 0;
|
||||||
@ -594,7 +594,7 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
skeleton = Json_getItem(root, "skeleton");
|
skeleton = Json_getItem(root, "skeleton");
|
||||||
if (skeleton) {
|
if (skeleton) {
|
||||||
MALLOC_STR(skeletonData->hash, Json_getString(skeleton, "hash", 0));
|
MALLOC_STR(skeletonData->hash, Json_getString(skeleton, "hash", 0));
|
||||||
MALLOC_STR(skeletonData->version, Json_getString(skeleton, "spine", 0));
|
MALLOC_STR(skeletonData->version, Json_getString(skeleton, "spine", 0));
|
||||||
skeletonData->width = Json_getFloat(skeleton, "width", 0);
|
skeletonData->width = Json_getFloat(skeleton, "width", 0);
|
||||||
skeletonData->height = Json_getFloat(skeleton, "height", 0);
|
skeletonData->height = Json_getFloat(skeleton, "height", 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
application = {
|
application = {
|
||||||
content = {
|
content = {
|
||||||
width = 320,
|
width = 320,
|
||||||
height = 480,
|
height = 480,
|
||||||
scale = "letterBox",
|
scale = "letterBox",
|
||||||
fps = 60,
|
fps = 60,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -7,56 +7,56 @@ local activeSkeleton = 1
|
|||||||
local lastTime = 0
|
local lastTime = 0
|
||||||
|
|
||||||
function loadSkeleton(atlasFile, jsonFile, x, y, scale, animation, skin)
|
function loadSkeleton(atlasFile, jsonFile, x, y, scale, animation, skin)
|
||||||
-- to load an atlas, we need to define a function that returns
|
-- to load an atlas, we need to define a function that returns
|
||||||
-- a Corona paint object. This allows you to resolve images
|
-- a Corona paint object. This allows you to resolve images
|
||||||
-- however you see fit
|
-- however you see fit
|
||||||
local imageLoader = function (path)
|
local imageLoader = function (path)
|
||||||
local paint = { type = "image", filename = "data/" .. path }
|
local paint = { type = "image", filename = "data/" .. path }
|
||||||
return paint
|
return paint
|
||||||
end
|
end
|
||||||
|
|
||||||
-- load the atlas
|
-- load the atlas
|
||||||
local atlas = spine.TextureAtlas.new(spine.utils.readFile("data/" .. atlasFile), imageLoader)
|
local atlas = spine.TextureAtlas.new(spine.utils.readFile("data/" .. atlasFile), imageLoader)
|
||||||
|
|
||||||
-- load the JSON and create a Skeleton from it
|
-- load the JSON and create a Skeleton from it
|
||||||
local json = spine.SkeletonJson.new(spine.AtlasAttachmentLoader.new(atlas))
|
local json = spine.SkeletonJson.new(spine.AtlasAttachmentLoader.new(atlas))
|
||||||
json.scale = scale
|
json.scale = scale
|
||||||
local skeletonData = json:readSkeletonDataFile("data/" .. jsonFile)
|
local skeletonData = json:readSkeletonDataFile("data/" .. jsonFile)
|
||||||
local skeleton = spine.Skeleton.new(skeletonData)
|
local skeleton = spine.Skeleton.new(skeletonData)
|
||||||
skeleton.flipY = true -- Corona's coordinate system has its y-axis point downwards
|
skeleton.flipY = true -- Corona's coordinate system has its y-axis point downwards
|
||||||
skeleton.group.x = x
|
skeleton.group.x = x
|
||||||
skeleton.group.y = y
|
skeleton.group.y = y
|
||||||
|
|
||||||
-- Set the skin if we got one
|
-- Set the skin if we got one
|
||||||
if skin then skeleton:setSkin(skin) end
|
if skin then skeleton:setSkin(skin) end
|
||||||
|
|
||||||
-- create an animation state object to apply animations to the skeleton
|
-- create an animation state object to apply animations to the skeleton
|
||||||
local animationStateData = spine.AnimationStateData.new(skeletonData)
|
local animationStateData = spine.AnimationStateData.new(skeletonData)
|
||||||
local animationState = spine.AnimationState.new(animationStateData)
|
local animationState = spine.AnimationState.new(animationStateData)
|
||||||
animationState:setAnimationByName(0, animation, true)
|
animationState:setAnimationByName(0, animation, true)
|
||||||
|
|
||||||
-- set the skeleton invisible
|
-- set the skeleton invisible
|
||||||
skeleton.group.isVisible = false
|
skeleton.group.isVisible = false
|
||||||
|
|
||||||
-- set a name on the group of the skeleton so we can find it during debugging
|
-- set a name on the group of the skeleton so we can find it during debugging
|
||||||
skeleton.group.name = jsonFile
|
skeleton.group.name = jsonFile
|
||||||
|
|
||||||
-- set some event callbacks
|
-- set some event callbacks
|
||||||
animationState.onStart = function (trackIndex)
|
animationState.onStart = function (trackIndex)
|
||||||
print(trackIndex.." start: "..animationState:getCurrent(trackIndex).animation.name)
|
print(trackIndex.." start: "..animationState:getCurrent(trackIndex).animation.name)
|
||||||
end
|
end
|
||||||
animationState.onEnd = function (trackIndex)
|
animationState.onEnd = function (trackIndex)
|
||||||
print(trackIndex.." end: "..animationState:getCurrent(trackIndex).animation.name)
|
print(trackIndex.." end: "..animationState:getCurrent(trackIndex).animation.name)
|
||||||
end
|
end
|
||||||
animationState.onComplete = function (trackIndex, loopCount)
|
animationState.onComplete = function (trackIndex, loopCount)
|
||||||
print(trackIndex.." complete: "..animationState:getCurrent(trackIndex).animation.name..", "..loopCount)
|
print(trackIndex.." complete: "..animationState:getCurrent(trackIndex).animation.name..", "..loopCount)
|
||||||
end
|
end
|
||||||
animationState.onEvent = function (trackIndex, event)
|
animationState.onEvent = function (trackIndex, event)
|
||||||
print(trackIndex.." event: "..animationState:getCurrent(trackIndex).animation.name..", "..event.data.name..", "..event.intValue..", "..event.floatValue..", '"..(event.stringValue or "").."'")
|
print(trackIndex.." event: "..animationState:getCurrent(trackIndex).animation.name..", "..event.data.name..", "..event.intValue..", "..event.floatValue..", '"..(event.stringValue or "").."'")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- return the skeleton an animation state
|
-- return the skeleton an animation state
|
||||||
return { skeleton = skeleton, state = animationState }
|
return { skeleton = skeleton, state = animationState }
|
||||||
end
|
end
|
||||||
|
|
||||||
table.insert(skeletons, loadSkeleton("spineboy.atlas", "spineboy.json", 240, 300, 0.4, "walk"))
|
table.insert(skeletons, loadSkeleton("spineboy.atlas", "spineboy.json", 240, 300, 0.4, "walk"))
|
||||||
@ -68,26 +68,26 @@ table.insert(skeletons, loadSkeleton("vine.atlas", "vine.json", 240, 300, 0.3, "
|
|||||||
|
|
||||||
display.setDefault("background", 0.2, 0.2, 0.2, 1)
|
display.setDefault("background", 0.2, 0.2, 0.2, 1)
|
||||||
|
|
||||||
Runtime:addEventListener("enterFrame", function (event)
|
Runtime:addEventListener("enterFrame", function (event)
|
||||||
local currentTime = event.time / 1000
|
local currentTime = event.time / 1000
|
||||||
local delta = currentTime - lastTime
|
local delta = currentTime - lastTime
|
||||||
lastTime = currentTime
|
lastTime = currentTime
|
||||||
|
|
||||||
skeleton = skeletons[activeSkeleton].skeleton
|
skeleton = skeletons[activeSkeleton].skeleton
|
||||||
skeleton.group.isVisible = true
|
skeleton.group.isVisible = true
|
||||||
state = skeletons[activeSkeleton].state
|
state = skeletons[activeSkeleton].state
|
||||||
|
|
||||||
state:update(delta)
|
state:update(delta)
|
||||||
state:apply(skeleton)
|
state:apply(skeleton)
|
||||||
skeleton:updateWorldTransform()
|
skeleton:updateWorldTransform()
|
||||||
|
|
||||||
-- uncomment if you want to know how many batches a skeleton renders to
|
-- uncomment if you want to know how many batches a skeleton renders to
|
||||||
-- print(skeleton.batches)
|
-- print(skeleton.batches)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
Runtime:addEventListener("tap", function(event)
|
Runtime:addEventListener("tap", function(event)
|
||||||
skeletons[activeSkeleton].skeleton.group.isVisible = false
|
skeletons[activeSkeleton].skeleton.group.isVisible = false
|
||||||
activeSkeleton = activeSkeleton + 1
|
activeSkeleton = activeSkeleton + 1
|
||||||
if activeSkeleton > #skeletons then activeSkeleton = 1 end
|
if activeSkeleton > #skeletons then activeSkeleton = 1 end
|
||||||
skeletons[activeSkeleton].skeleton.group.isVisible = true
|
skeletons[activeSkeleton].skeleton.group.isVisible = true
|
||||||
end)
|
end)
|
||||||
File diff suppressed because it is too large
Load Diff
@ -71,7 +71,7 @@ spine.utils.readFile = function (fileName, base)
|
|||||||
io.close(file)
|
io.close(file)
|
||||||
return contents
|
return contents
|
||||||
end
|
end
|
||||||
|
|
||||||
local json = require "json"
|
local json = require "json"
|
||||||
spine.utils.readJSON = function (text)
|
spine.utils.readJSON = function (text)
|
||||||
return json.decode(text)
|
return json.decode(text)
|
||||||
@ -111,15 +111,15 @@ end
|
|||||||
function spine.Skeleton:updateWorldTransform()
|
function spine.Skeleton:updateWorldTransform()
|
||||||
spine.Skeleton.updateWorldTransform_super(self)
|
spine.Skeleton.updateWorldTransform_super(self)
|
||||||
local premultipliedAlpha = self.premultipliedAlpha
|
local premultipliedAlpha = self.premultipliedAlpha
|
||||||
|
|
||||||
self.batches = 0
|
self.batches = 0
|
||||||
|
|
||||||
-- Remove old drawing group, we will start anew
|
-- Remove old drawing group, we will start anew
|
||||||
if self.drawingGroup then self.drawingGroup:removeSelf() end
|
if self.drawingGroup then self.drawingGroup:removeSelf() end
|
||||||
local drawingGroup = display.newGroup()
|
local drawingGroup = display.newGroup()
|
||||||
self.drawingGroup = drawingGroup
|
self.drawingGroup = drawingGroup
|
||||||
self.group:insert(drawingGroup)
|
self.group:insert(drawingGroup)
|
||||||
|
|
||||||
local drawOrder = self.drawOrder
|
local drawOrder = self.drawOrder
|
||||||
local currentGroup = nil
|
local currentGroup = nil
|
||||||
local groupVertices = {}
|
local groupVertices = {}
|
||||||
@ -149,12 +149,12 @@ function spine.Skeleton:updateWorldTransform()
|
|||||||
color = { vertices[5], vertices[6], vertices[7], vertices[8] }
|
color = { vertices[5], vertices[6], vertices[7], vertices[8] }
|
||||||
blendMode = toCoronaBlendMode(slot.data.blendMode)
|
blendMode = toCoronaBlendMode(slot.data.blendMode)
|
||||||
end
|
end
|
||||||
|
|
||||||
if texture and vertices and indices then
|
if texture and vertices and indices then
|
||||||
if not lastTexture then lastTexture = texture end
|
if not lastTexture then lastTexture = texture end
|
||||||
if not lastColor then lastColor = color end
|
if not lastColor then lastColor = color end
|
||||||
if not lastBlendMode then lastBlendMode = blendMode end
|
if not lastBlendMode then lastBlendMode = blendMode end
|
||||||
|
|
||||||
if (texture ~= lastTexture or not colorEquals(color, lastColor) or blendMode ~= lastBlendMode) then
|
if (texture ~= lastTexture or not colorEquals(color, lastColor) or blendMode ~= lastBlendMode) then
|
||||||
self:flush(groupVertices, groupUvs, groupIndices, lastTexture, lastColor, lastBlendMode, drawingGroup)
|
self:flush(groupVertices, groupUvs, groupIndices, lastTexture, lastColor, lastBlendMode, drawingGroup)
|
||||||
lastTexture = texture
|
lastTexture = texture
|
||||||
@ -164,12 +164,12 @@ function spine.Skeleton:updateWorldTransform()
|
|||||||
groupUvs = {}
|
groupUvs = {}
|
||||||
groupIndices = {}
|
groupIndices = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
self:batch(vertices, indices, groupVertices, groupUvs, groupIndices)
|
self:batch(vertices, indices, groupVertices, groupUvs, groupIndices)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if #groupVertices > 0 then
|
if #groupVertices > 0 then
|
||||||
self:flush(groupVertices, groupUvs, groupIndices, texture, color, blendMode, drawingGroup)
|
self:flush(groupVertices, groupUvs, groupIndices, texture, color, blendMode, drawingGroup)
|
||||||
end
|
end
|
||||||
@ -202,7 +202,7 @@ function spine.Skeleton:batch(vertices, indices, groupVertices, groupUvs, groupI
|
|||||||
indexStart = indexStart + 1
|
indexStart = indexStart + 1
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
i = 1
|
i = 1
|
||||||
local numVertices = #vertices
|
local numVertices = #vertices
|
||||||
local vertexStart = #groupVertices + 1
|
local vertexStart = #groupVertices + 1
|
||||||
|
|||||||
@ -661,7 +661,7 @@ namespace Spine {
|
|||||||
: base(frameCount) {
|
: base(frameCount) {
|
||||||
frames = new float[frameCount * ENTRIES];
|
frames = new float[frameCount * ENTRIES];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Sets the time, mix and bend direction of the specified keyframe.</summary>
|
/// <summary>Sets the time, mix and bend direction of the specified keyframe.</summary>
|
||||||
public void SetFrame (int frameIndex, float time, float mix, int bendDirection) {
|
public void SetFrame (int frameIndex, float time, float mix, int bendDirection) {
|
||||||
frameIndex *= ENTRIES;
|
frameIndex *= ENTRIES;
|
||||||
@ -836,7 +836,7 @@ namespace Spine {
|
|||||||
public PathConstraintMixTimeline (int frameCount)
|
public PathConstraintMixTimeline (int frameCount)
|
||||||
: base(frameCount) {
|
: base(frameCount) {
|
||||||
frames = new float[frameCount * ENTRIES];
|
frames = new float[frameCount * ENTRIES];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the time and mixes of the specified keyframe. */
|
/** Sets the time and mixes of the specified keyframe. */
|
||||||
public void SetFrame (int frameIndex, float time, float rotateMix, float translateMix) {
|
public void SetFrame (int frameIndex, float time, float rotateMix, float translateMix) {
|
||||||
|
|||||||
@ -71,7 +71,7 @@ namespace Spine {
|
|||||||
attachment.regionOriginalWidth = region.originalWidth;
|
attachment.regionOriginalWidth = region.originalWidth;
|
||||||
attachment.regionOriginalHeight = region.originalHeight;
|
attachment.regionOriginalHeight = region.originalHeight;
|
||||||
return attachment;
|
return attachment;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, String name) {
|
public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, String name) {
|
||||||
return new BoundingBoxAttachment(name);
|
return new BoundingBoxAttachment(name);
|
||||||
|
|||||||
@ -43,6 +43,6 @@ namespace Spine {
|
|||||||
|
|
||||||
public PathAttachment (String name)
|
public PathAttachment (String name)
|
||||||
: base(name) {
|
: base(name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -136,7 +136,7 @@ namespace Spine {
|
|||||||
|
|
||||||
public void ComputeWorldVertices (Bone bone, float[] worldVertices) {
|
public void ComputeWorldVertices (Bone bone, float[] worldVertices) {
|
||||||
Skeleton skeleton = bone.skeleton;
|
Skeleton skeleton = bone.skeleton;
|
||||||
float x = skeleton.x + bone.worldX, y = skeleton.y + bone.worldY;
|
float x = skeleton.x + bone.worldX, y = skeleton.y + bone.worldY;
|
||||||
float a = bone.a, b = bone.b, c = bone.c, d = bone.d;
|
float a = bone.a, b = bone.b, c = bone.c, d = bone.d;
|
||||||
float[] offset = this.offset;
|
float[] offset = this.offset;
|
||||||
worldVertices[X1] = offset[X1] * a + offset[Y1] * b + x;
|
worldVertices[X1] = offset[X1] * a + offset[Y1] * b + x;
|
||||||
|
|||||||
@ -112,6 +112,6 @@ namespace Spine {
|
|||||||
/// <summary>Returns true if a deform originally applied to the specified attachment should be applied to this attachment.</summary>
|
/// <summary>Returns true if a deform originally applied to the specified attachment should be applied to this attachment.</summary>
|
||||||
virtual public bool ApplyDeform (VertexAttachment sourceAttachment) {
|
virtual public bool ApplyDeform (VertexAttachment sourceAttachment) {
|
||||||
return this == sourceAttachment;
|
return this == sourceAttachment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -294,7 +294,7 @@ namespace Spine {
|
|||||||
appliedRotation = rotation;
|
appliedRotation = rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WorldToLocal (float worldX, float worldY, out float localX, out float localY) {
|
public void WorldToLocal (float worldX, float worldY, out float localX, out float localY) {
|
||||||
float a = this.a, b = this.b, c = this.c, d = this.d;
|
float a = this.a, b = this.b, c = this.c, d = this.d;
|
||||||
float invDet = 1 / (a * d - b * c);
|
float invDet = 1 / (a * d - b * c);
|
||||||
float x = worldX - this.worldX, y = worldY - this.worldY;
|
float x = worldX - this.worldX, y = worldY - this.worldY;
|
||||||
|
|||||||
@ -54,7 +54,7 @@ namespace Spine {
|
|||||||
*
|
*
|
||||||
* Changes made:
|
* Changes made:
|
||||||
*
|
*
|
||||||
* - Optimized parser speed (deserialize roughly near 3x faster than original)
|
* - Optimized parser speed (deserialize roughly near 3x faster than original)
|
||||||
* - Added support to handle lexer/parser error messages with line numbers
|
* - Added support to handle lexer/parser error messages with line numbers
|
||||||
* - Added more fine grained control over type conversions during the parsing
|
* - Added more fine grained control over type conversions during the parsing
|
||||||
* - Refactory API (Separate Lexer code from Parser code and the Encoder from Decoder)
|
* - Refactory API (Separate Lexer code from Parser code and the Encoder from Decoder)
|
||||||
@ -133,19 +133,19 @@ namespace SharpJson
|
|||||||
{
|
{
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
StringBuilder builder = null;
|
StringBuilder builder = null;
|
||||||
|
|
||||||
SkipWhiteSpaces();
|
SkipWhiteSpaces();
|
||||||
|
|
||||||
// "
|
// "
|
||||||
char c = json[index++];
|
char c = json[index++];
|
||||||
|
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
bool complete = false;
|
bool complete = false;
|
||||||
|
|
||||||
while (!complete && !failed) {
|
while (!complete && !failed) {
|
||||||
if (index == json.Length)
|
if (index == json.Length)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
c = json[index++];
|
c = json[index++];
|
||||||
if (c == '"') {
|
if (c == '"') {
|
||||||
complete = true;
|
complete = true;
|
||||||
@ -153,9 +153,9 @@ namespace SharpJson
|
|||||||
} else if (c == '\\') {
|
} else if (c == '\\') {
|
||||||
if (index == json.Length)
|
if (index == json.Length)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
c = json[index++];
|
c = json[index++];
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '"':
|
case '"':
|
||||||
stringBuffer[idx++] = '"';
|
stringBuffer[idx++] = '"';
|
||||||
@ -185,10 +185,10 @@ namespace SharpJson
|
|||||||
int remainingLength = json.Length - index;
|
int remainingLength = json.Length - index;
|
||||||
if (remainingLength >= 4) {
|
if (remainingLength >= 4) {
|
||||||
var hex = new string(json, index, 4);
|
var hex = new string(json, index, 4);
|
||||||
|
|
||||||
// XXX: handle UTF
|
// XXX: handle UTF
|
||||||
stringBuffer[idx++] = (char) Convert.ToInt32(hex, 16);
|
stringBuffer[idx++] = (char) Convert.ToInt32(hex, 16);
|
||||||
|
|
||||||
// skip 4 chars
|
// skip 4 chars
|
||||||
index += 4;
|
index += 4;
|
||||||
} else {
|
} else {
|
||||||
@ -199,38 +199,38 @@ namespace SharpJson
|
|||||||
} else {
|
} else {
|
||||||
stringBuffer[idx++] = c;
|
stringBuffer[idx++] = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idx >= stringBuffer.Length) {
|
if (idx >= stringBuffer.Length) {
|
||||||
if (builder == null)
|
if (builder == null)
|
||||||
builder = new StringBuilder();
|
builder = new StringBuilder();
|
||||||
|
|
||||||
builder.Append(stringBuffer, 0, idx);
|
builder.Append(stringBuffer, 0, idx);
|
||||||
idx = 0;
|
idx = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!complete) {
|
if (!complete) {
|
||||||
success = false;
|
success = false;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (builder != null)
|
if (builder != null)
|
||||||
return builder.ToString ();
|
return builder.ToString ();
|
||||||
else
|
else
|
||||||
return new string (stringBuffer, 0, idx);
|
return new string (stringBuffer, 0, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
string GetNumberString()
|
string GetNumberString()
|
||||||
{
|
{
|
||||||
SkipWhiteSpaces();
|
SkipWhiteSpaces();
|
||||||
|
|
||||||
int lastIndex = GetLastIndexOfNumber(index);
|
int lastIndex = GetLastIndexOfNumber(index);
|
||||||
int charLength = (lastIndex - index) + 1;
|
int charLength = (lastIndex - index) + 1;
|
||||||
|
|
||||||
var result = new string (json, index, charLength);
|
var result = new string (json, index, charLength);
|
||||||
|
|
||||||
index = lastIndex + 1;
|
index = lastIndex + 1;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,10 +238,10 @@ namespace SharpJson
|
|||||||
{
|
{
|
||||||
float number;
|
float number;
|
||||||
var str = GetNumberString ();
|
var str = GetNumberString ();
|
||||||
|
|
||||||
if (!float.TryParse (str, NumberStyles.Float, CultureInfo.InvariantCulture, out number))
|
if (!float.TryParse (str, NumberStyles.Float, CultureInfo.InvariantCulture, out number))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return number;
|
return number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,25 +249,24 @@ namespace SharpJson
|
|||||||
{
|
{
|
||||||
double number;
|
double number;
|
||||||
var str = GetNumberString ();
|
var str = GetNumberString ();
|
||||||
|
|
||||||
if (!double.TryParse(str, NumberStyles.Any, CultureInfo.InvariantCulture, out number))
|
if (!double.TryParse(str, NumberStyles.Any, CultureInfo.InvariantCulture, out number))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return number;
|
return number;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetLastIndexOfNumber(int index)
|
int GetLastIndexOfNumber(int index)
|
||||||
{
|
{
|
||||||
int lastIndex;
|
int lastIndex;
|
||||||
|
|
||||||
for (lastIndex = index; lastIndex < json.Length; lastIndex++) {
|
for (lastIndex = index; lastIndex < json.Length; lastIndex++) {
|
||||||
char ch = json[lastIndex];
|
char ch = json[lastIndex];
|
||||||
|
|
||||||
if ((ch < '0' || ch > '9') && ch != '+' && ch != '-'
|
if ((ch < '0' || ch > '9') && ch != '+' && ch != '-' && ch != '.' && ch != 'e' && ch != 'E')
|
||||||
&& ch != '.' && ch != 'e' && ch != 'E')
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return lastIndex - 1;
|
return lastIndex - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,9 +301,9 @@ namespace SharpJson
|
|||||||
{
|
{
|
||||||
if (index == json.Length)
|
if (index == json.Length)
|
||||||
return Token.None;
|
return Token.None;
|
||||||
|
|
||||||
char c = json[index++];
|
char c = json[index++];
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '{':
|
case '{':
|
||||||
return Token.CurlyOpen;
|
return Token.CurlyOpen;
|
||||||
@ -327,38 +326,41 @@ namespace SharpJson
|
|||||||
}
|
}
|
||||||
|
|
||||||
index--;
|
index--;
|
||||||
|
|
||||||
int remainingLength = json.Length - index;
|
int remainingLength = json.Length - index;
|
||||||
|
|
||||||
// false
|
// false
|
||||||
if (remainingLength >= 5) {
|
if (remainingLength >= 5) {
|
||||||
if (json[index] == 'f' &&
|
if (json[index] == 'f' &&
|
||||||
json[index + 1] == 'a' &&
|
json[index + 1] == 'a' &&
|
||||||
json[index + 2] == 'l' &&
|
json[index + 2] == 'l' &&
|
||||||
json[index + 3] == 's' &&
|
json[index + 3] == 's' &&
|
||||||
json[index + 4] == 'e') {
|
json[index + 4] == 'e'
|
||||||
|
) {
|
||||||
index += 5;
|
index += 5;
|
||||||
return Token.False;
|
return Token.False;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// true
|
// true
|
||||||
if (remainingLength >= 4) {
|
if (remainingLength >= 4) {
|
||||||
if (json[index] == 't' &&
|
if (json[index] == 't' &&
|
||||||
json[index + 1] == 'r' &&
|
json[index + 1] == 'r' &&
|
||||||
json[index + 2] == 'u' &&
|
json[index + 2] == 'u' &&
|
||||||
json[index + 3] == 'e') {
|
json[index + 3] == 'e'
|
||||||
|
) {
|
||||||
index += 4;
|
index += 4;
|
||||||
return Token.True;
|
return Token.True;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// null
|
// null
|
||||||
if (remainingLength >= 4) {
|
if (remainingLength >= 4) {
|
||||||
if (json[index] == 'n' &&
|
if (json[index] == 'n' &&
|
||||||
json[index + 1] == 'u' &&
|
json[index + 1] == 'u' &&
|
||||||
json[index + 2] == 'l' &&
|
json[index + 2] == 'l' &&
|
||||||
json[index + 3] == 'l') {
|
json[index + 3] == 'l'
|
||||||
|
) {
|
||||||
index += 4;
|
index += 4;
|
||||||
return Token.Null;
|
return Token.Null;
|
||||||
}
|
}
|
||||||
@ -438,25 +440,25 @@ namespace SharpJson
|
|||||||
TriggerError("Invalid token; expected ':'");
|
TriggerError("Invalid token; expected ':'");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// value
|
// value
|
||||||
object value = ParseValue();
|
object value = ParseValue();
|
||||||
|
|
||||||
if (errorMessage != null)
|
if (errorMessage != null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
table[name] = value;
|
table[name] = value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//return null; // Unreachable code
|
//return null; // Unreachable code
|
||||||
}
|
}
|
||||||
|
|
||||||
IList<object> ParseArray()
|
IList<object> ParseArray()
|
||||||
{
|
{
|
||||||
var array = new List<object>();
|
var array = new List<object>();
|
||||||
|
|
||||||
// [
|
// [
|
||||||
lexer.NextToken();
|
lexer.NextToken();
|
||||||
|
|
||||||
@ -483,7 +485,7 @@ namespace SharpJson
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//return null; // Unreachable code
|
//return null; // Unreachable code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -62,12 +62,12 @@ namespace Spine {
|
|||||||
static public float Cos (float radians) {
|
static public float Cos (float radians) {
|
||||||
return sin[(int)((radians + PI / 2) * radToIndex) & SIN_MASK];
|
return sin[(int)((radians + PI / 2) * radToIndex) & SIN_MASK];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Returns the sine in radians from a lookup table.</summary>
|
/// <summary>Returns the sine in radians from a lookup table.</summary>
|
||||||
static public float SinDeg (float degrees) {
|
static public float SinDeg (float degrees) {
|
||||||
return sin[(int)(degrees * degToIndex) & SIN_MASK];
|
return sin[(int)(degrees * degToIndex) & SIN_MASK];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Returns the cosine in radians from a lookup table.</summary>
|
/// <summary>Returns the cosine in radians from a lookup table.</summary>
|
||||||
static public float CosDeg (float degrees) {
|
static public float CosDeg (float degrees) {
|
||||||
return sin[(int)((degrees + 90) * degToIndex) & SIN_MASK];
|
return sin[(int)((degrees + 90) * degToIndex) & SIN_MASK];
|
||||||
|
|||||||
@ -68,7 +68,7 @@ namespace Spine {
|
|||||||
public void Apply () {
|
public void Apply () {
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update () {
|
public void Update () {
|
||||||
PathAttachment attachment = target.Attachment as PathAttachment;
|
PathAttachment attachment = target.Attachment as PathAttachment;
|
||||||
if (attachment == null) return;
|
if (attachment == null) return;
|
||||||
|
|||||||
@ -42,7 +42,7 @@ namespace Spine {
|
|||||||
internal float position, spacing, rotateMix, translateMix;
|
internal float position, spacing, rotateMix, translateMix;
|
||||||
|
|
||||||
public ExposedList<BoneData> Bones { get { return bones; } }
|
public ExposedList<BoneData> Bones { get { return bones; } }
|
||||||
public SlotData Target { get { return target; } set { target = value; } }
|
public SlotData Target { get { return target; } set { target = value; } }
|
||||||
public PositionMode PositionMode { get { return positionMode; } set { positionMode = value; } }
|
public PositionMode PositionMode { get { return positionMode; } set { positionMode = value; } }
|
||||||
public SpacingMode SpacingMode { get { return spacingMode; } set { spacingMode = value; } }
|
public SpacingMode SpacingMode { get { return spacingMode; } set { spacingMode = value; } }
|
||||||
public RotateMode RotateMode { get { return rotateMode; } set { rotateMode = value; } }
|
public RotateMode RotateMode { get { return rotateMode; } set { rotateMode = value; } }
|
||||||
@ -58,9 +58,9 @@ namespace Spine {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum PositionMode {
|
public enum PositionMode {
|
||||||
Fixed, Percent
|
Fixed, Percent
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SpacingMode {
|
public enum SpacingMode {
|
||||||
|
|||||||
@ -78,7 +78,7 @@ namespace Spine {
|
|||||||
foreach (BoneData boneData in data.bones) {
|
foreach (BoneData boneData in data.bones) {
|
||||||
Bone bone;
|
Bone bone;
|
||||||
if (boneData.parent == null) {
|
if (boneData.parent == null) {
|
||||||
bone = new Bone(boneData, this, null);
|
bone = new Bone(boneData, this, null);
|
||||||
} else {
|
} else {
|
||||||
Bone parent = bones.Items[boneData.parent.index];
|
Bone parent = bones.Items[boneData.parent.index];
|
||||||
bone = new Bone(boneData, this, parent);
|
bone = new Bone(boneData, this, parent);
|
||||||
@ -416,7 +416,7 @@ namespace Spine {
|
|||||||
}
|
}
|
||||||
throw new Exception("Slot not found: " + slotName);
|
throw new Exception("Slot not found: " + slotName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <returns>May be null.</returns>
|
/// <returns>May be null.</returns>
|
||||||
public IkConstraint FindIkConstraint (String constraintName) {
|
public IkConstraint FindIkConstraint (String constraintName) {
|
||||||
if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null.");
|
if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null.");
|
||||||
|
|||||||
@ -74,7 +74,7 @@ namespace Spine {
|
|||||||
this.attachmentLoader = attachmentLoader;
|
this.attachmentLoader = attachmentLoader;
|
||||||
Scale = 1;
|
Scale = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !ISUNITY && WINDOWS_STOREAPP
|
#if !ISUNITY && WINDOWS_STOREAPP
|
||||||
private async Task<SkeletonData> ReadFile(string path) {
|
private async Task<SkeletonData> ReadFile(string path) {
|
||||||
var folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
|
var folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
|
||||||
@ -127,7 +127,7 @@ namespace Spine {
|
|||||||
String name = ReadString(input);
|
String name = ReadString(input);
|
||||||
BoneData parent = i == 0 ? null : skeletonData.bones.Items[ReadVarint(input, true)];
|
BoneData parent = i == 0 ? null : skeletonData.bones.Items[ReadVarint(input, true)];
|
||||||
BoneData data = new BoneData(i, name, parent);
|
BoneData data = new BoneData(i, name, parent);
|
||||||
data.rotation = ReadFloat(input);
|
data.rotation = ReadFloat(input);
|
||||||
data.x = ReadFloat(input) * scale;
|
data.x = ReadFloat(input) * scale;
|
||||||
data.y = ReadFloat(input) * scale;
|
data.y = ReadFloat(input) * scale;
|
||||||
data.scaleX = ReadFloat(input);
|
data.scaleX = ReadFloat(input);
|
||||||
@ -171,7 +171,7 @@ namespace Spine {
|
|||||||
for (int i = 0, n = ReadVarint(input, true); i < n; i++) {
|
for (int i = 0, n = ReadVarint(input, true); i < n; i++) {
|
||||||
TransformConstraintData data = new TransformConstraintData(ReadString(input));
|
TransformConstraintData data = new TransformConstraintData(ReadString(input));
|
||||||
for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++)
|
for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++)
|
||||||
data.bones.Add(skeletonData.bones.Items[ReadVarint(input, true)]);
|
data.bones.Add(skeletonData.bones.Items[ReadVarint(input, true)]);
|
||||||
data.target = skeletonData.bones.Items[ReadVarint(input, true)];
|
data.target = skeletonData.bones.Items[ReadVarint(input, true)];
|
||||||
data.offsetRotation = ReadFloat(input);
|
data.offsetRotation = ReadFloat(input);
|
||||||
data.offsetX = ReadFloat(input) * scale;
|
data.offsetX = ReadFloat(input) * scale;
|
||||||
@ -277,7 +277,7 @@ namespace Spine {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case AttachmentType.Region: {
|
case AttachmentType.Region: {
|
||||||
String path = ReadString(input);
|
String path = ReadString(input);
|
||||||
float rotation = ReadFloat(input);
|
float rotation = ReadFloat(input);
|
||||||
float x = ReadFloat(input);
|
float x = ReadFloat(input);
|
||||||
float y = ReadFloat(input);
|
float y = ReadFloat(input);
|
||||||
float scaleX = ReadFloat(input);
|
float scaleX = ReadFloat(input);
|
||||||
@ -308,18 +308,18 @@ namespace Spine {
|
|||||||
int vertexCount = ReadVarint(input, true);
|
int vertexCount = ReadVarint(input, true);
|
||||||
Vertices vertices = ReadVertices(input, vertexCount);
|
Vertices vertices = ReadVertices(input, vertexCount);
|
||||||
if (nonessential) ReadInt(input); //int color = nonessential ? ReadInt(input) : 0; // Avoid unused local warning.
|
if (nonessential) ReadInt(input); //int color = nonessential ? ReadInt(input) : 0; // Avoid unused local warning.
|
||||||
|
|
||||||
BoundingBoxAttachment box = attachmentLoader.NewBoundingBoxAttachment(skin, name);
|
BoundingBoxAttachment box = attachmentLoader.NewBoundingBoxAttachment(skin, name);
|
||||||
if (box == null) return null;
|
if (box == null) return null;
|
||||||
box.worldVerticesLength = vertexCount << 1;
|
box.worldVerticesLength = vertexCount << 1;
|
||||||
box.vertices = vertices.vertices;
|
box.vertices = vertices.vertices;
|
||||||
box.bones = vertices.bones;
|
box.bones = vertices.bones;
|
||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
case AttachmentType.Mesh: {
|
case AttachmentType.Mesh: {
|
||||||
String path = ReadString(input);
|
String path = ReadString(input);
|
||||||
int color = ReadInt(input);
|
int color = ReadInt(input);
|
||||||
int vertexCount = ReadVarint(input, true);
|
int vertexCount = ReadVarint(input, true);
|
||||||
float[] uvs = ReadFloatArray(input, vertexCount << 1, 1);
|
float[] uvs = ReadFloatArray(input, vertexCount << 1, 1);
|
||||||
int[] triangles = ReadShortArray(input);
|
int[] triangles = ReadShortArray(input);
|
||||||
Vertices vertices = ReadVertices(input, vertexCount);
|
Vertices vertices = ReadVertices(input, vertexCount);
|
||||||
@ -400,8 +400,8 @@ namespace Spine {
|
|||||||
path.vertices = vertices.vertices;
|
path.vertices = vertices.vertices;
|
||||||
path.bones = vertices.bones;
|
path.bones = vertices.bones;
|
||||||
path.lengths = lengths;
|
path.lengths = lengths;
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -540,7 +540,7 @@ namespace Spine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IK timelines.
|
// IK timelines.
|
||||||
for (int i = 0, n = ReadVarint(input, true); i < n; i++) {
|
for (int i = 0, n = ReadVarint(input, true); i < n; i++) {
|
||||||
int index = ReadVarint(input, true);
|
int index = ReadVarint(input, true);
|
||||||
int frameCount = ReadVarint(input, true);
|
int frameCount = ReadVarint(input, true);
|
||||||
IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount);
|
IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount);
|
||||||
@ -587,7 +587,7 @@ namespace Spine {
|
|||||||
if (data.positionMode == PositionMode.Fixed) timelineScale = scale;
|
if (data.positionMode == PositionMode.Fixed) timelineScale = scale;
|
||||||
}
|
}
|
||||||
timeline.pathConstraintIndex = index;
|
timeline.pathConstraintIndex = index;
|
||||||
for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||||
timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input) * timelineScale);
|
timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input) * timelineScale);
|
||||||
if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline);
|
if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline);
|
||||||
}
|
}
|
||||||
@ -651,7 +651,7 @@ namespace Spine {
|
|||||||
|
|
||||||
timeline.SetFrame(frameIndex, time, deform);
|
timeline.SetFrame(frameIndex, time, deform);
|
||||||
if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline);
|
if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline);
|
||||||
}
|
}
|
||||||
timelines.Add(timeline);
|
timelines.Add(timeline);
|
||||||
duration = Math.Max(duration, timeline.frames[frameCount - 1]);
|
duration = Math.Max(duration, timeline.frames[frameCount - 1]);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -144,7 +144,7 @@ namespace Spine {
|
|||||||
data.b = ToColor(color, 2);
|
data.b = ToColor(color, 2);
|
||||||
data.a = ToColor(color, 3);
|
data.a = ToColor(color, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
data.attachmentName = GetString(slotMap, "attachment", null);
|
data.attachmentName = GetString(slotMap, "attachment", null);
|
||||||
if (slotMap.ContainsKey("blend"))
|
if (slotMap.ContainsKey("blend"))
|
||||||
data.blendMode = (BlendMode)Enum.Parse(typeof(BlendMode), (String)slotMap["blend"], false);
|
data.blendMode = (BlendMode)Enum.Parse(typeof(BlendMode), (String)slotMap["blend"], false);
|
||||||
@ -164,7 +164,7 @@ namespace Spine {
|
|||||||
if (bone == null) throw new Exception("IK constraint bone not found: " + boneName);
|
if (bone == null) throw new Exception("IK constraint bone not found: " + boneName);
|
||||||
data.bones.Add(bone);
|
data.bones.Add(bone);
|
||||||
}
|
}
|
||||||
|
|
||||||
String targetName = (String)constraintMap["target"];
|
String targetName = (String)constraintMap["target"];
|
||||||
data.target = skeletonData.FindBone(targetName);
|
data.target = skeletonData.FindBone(targetName);
|
||||||
if (data.target == null) throw new Exception("Target bone not found: " + targetName);
|
if (data.target == null) throw new Exception("Target bone not found: " + targetName);
|
||||||
@ -289,7 +289,7 @@ namespace Spine {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new Exception("Error reading animation: " + entry.Key, e);
|
throw new Exception("Error reading animation: " + entry.Key, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
skeletonData.bones.TrimExcess();
|
skeletonData.bones.TrimExcess();
|
||||||
@ -632,7 +632,7 @@ namespace Spine {
|
|||||||
var timeline = new DeformTimeline(values.Count);
|
var timeline = new DeformTimeline(values.Count);
|
||||||
timeline.slotIndex = slotIndex;
|
timeline.slotIndex = slotIndex;
|
||||||
timeline.attachment = attachment;
|
timeline.attachment = attachment;
|
||||||
|
|
||||||
int frameIndex = 0;
|
int frameIndex = 0;
|
||||||
foreach (Dictionary<String, Object> valueMap in values) {
|
foreach (Dictionary<String, Object> valueMap in values) {
|
||||||
float[] deform;
|
float[] deform;
|
||||||
|
|||||||
@ -57,7 +57,7 @@ namespace Spine {
|
|||||||
bones = new ExposedList<Bone>();
|
bones = new ExposedList<Bone>();
|
||||||
foreach (BoneData boneData in data.bones)
|
foreach (BoneData boneData in data.bones)
|
||||||
bones.Add (skeleton.FindBone (boneData.name));
|
bones.Add (skeleton.FindBone (boneData.name));
|
||||||
|
|
||||||
target = skeleton.FindBone(data.target.name);
|
target = skeleton.FindBone(data.target.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -34,74 +34,74 @@ local skeletons = {}
|
|||||||
local activeSkeleton = 1
|
local activeSkeleton = 1
|
||||||
|
|
||||||
function loadSkeleton (jsonFile, atlasFile, animation, skin, scale, x, y)
|
function loadSkeleton (jsonFile, atlasFile, animation, skin, scale, x, y)
|
||||||
local loader = function (path) return love.graphics.newImage("data/" .. path) end
|
local loader = function (path) return love.graphics.newImage("data/" .. path) end
|
||||||
local atlas = spine.TextureAtlas.new(spine.utils.readFile("data/" .. atlasFile .. ".atlas"), loader)
|
local atlas = spine.TextureAtlas.new(spine.utils.readFile("data/" .. atlasFile .. ".atlas"), loader)
|
||||||
|
|
||||||
local json = spine.SkeletonJson.new(spine.AtlasAttachmentLoader.new(atlas))
|
local json = spine.SkeletonJson.new(spine.AtlasAttachmentLoader.new(atlas))
|
||||||
json.scale = scale
|
json.scale = scale
|
||||||
local skeletonData = json:readSkeletonDataFile("data/" .. jsonFile .. ".json")
|
local skeletonData = json:readSkeletonDataFile("data/" .. jsonFile .. ".json")
|
||||||
local skeleton = spine.Skeleton.new(skeletonData)
|
local skeleton = spine.Skeleton.new(skeletonData)
|
||||||
skeleton.x = x
|
skeleton.x = x
|
||||||
skeleton.y = y
|
skeleton.y = y
|
||||||
skeleton.flipX = false
|
skeleton.flipX = false
|
||||||
skeleton.flipY = true
|
skeleton.flipY = true
|
||||||
if skin then
|
if skin then
|
||||||
skeleton:setSkin(skin)
|
skeleton:setSkin(skin)
|
||||||
end
|
end
|
||||||
skeleton:setToSetupPose()
|
skeleton:setToSetupPose()
|
||||||
|
|
||||||
local stateData = spine.AnimationStateData.new(skeletonData)
|
local stateData = spine.AnimationStateData.new(skeletonData)
|
||||||
local state = spine.AnimationState.new(stateData)
|
local state = spine.AnimationState.new(stateData)
|
||||||
state:setAnimationByName(0, animation, true)
|
state:setAnimationByName(0, animation, true)
|
||||||
|
|
||||||
state.onStart = function (trackIndex)
|
state.onStart = function (trackIndex)
|
||||||
print(trackIndex.." start: "..state:getCurrent(trackIndex).animation.name)
|
print(trackIndex.." start: "..state:getCurrent(trackIndex).animation.name)
|
||||||
end
|
end
|
||||||
state.onEnd = function (trackIndex)
|
state.onEnd = function (trackIndex)
|
||||||
print(trackIndex.." end: "..state:getCurrent(trackIndex).animation.name)
|
print(trackIndex.." end: "..state:getCurrent(trackIndex).animation.name)
|
||||||
end
|
end
|
||||||
state.onComplete = function (trackIndex, loopCount)
|
state.onComplete = function (trackIndex, loopCount)
|
||||||
print(trackIndex.." complete: "..state:getCurrent(trackIndex).animation.name..", "..loopCount)
|
print(trackIndex.." complete: "..state:getCurrent(trackIndex).animation.name..", "..loopCount)
|
||||||
end
|
end
|
||||||
state.onEvent = function (trackIndex, event)
|
state.onEvent = function (trackIndex, event)
|
||||||
print(trackIndex.." event: "..state:getCurrent(trackIndex).animation.name..", "..event.data.name..", "..event.intValue..", "..event.floatValue..", '"..(event.stringValue or "").."'")
|
print(trackIndex.." event: "..state:getCurrent(trackIndex).animation.name..", "..event.data.name..", "..event.intValue..", "..event.floatValue..", '"..(event.stringValue or "").."'")
|
||||||
end
|
end
|
||||||
|
|
||||||
state:update(0.5)
|
state:update(0.5)
|
||||||
state:apply(skeleton)
|
state:apply(skeleton)
|
||||||
|
|
||||||
return { state = state, skeleton = skeleton }
|
return { state = state, skeleton = skeleton }
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.load(arg)
|
function love.load(arg)
|
||||||
if arg[#arg] == "-debug" then require("mobdebug").start() end
|
if arg[#arg] == "-debug" then require("mobdebug").start() end
|
||||||
table.insert(skeletons, loadSkeleton("test", "test", "animation", nil, 0.5, 400, 300))
|
table.insert(skeletons, loadSkeleton("test", "test", "animation", nil, 0.5, 400, 300))
|
||||||
table.insert(skeletons, loadSkeleton("spineboy", "spineboy", "walk", nil, 0.5, 400, 500))
|
table.insert(skeletons, loadSkeleton("spineboy", "spineboy", "walk", nil, 0.5, 400, 500))
|
||||||
table.insert(skeletons, loadSkeleton("raptor", "raptor", "walk", nil, 0.3, 400, 500))
|
table.insert(skeletons, loadSkeleton("raptor", "raptor", "walk", nil, 0.3, 400, 500))
|
||||||
table.insert(skeletons, loadSkeleton("goblins-mesh", "goblins", "walk", "goblin", 1, 400, 500))
|
table.insert(skeletons, loadSkeleton("goblins-mesh", "goblins", "walk", "goblin", 1, 400, 500))
|
||||||
table.insert(skeletons, loadSkeleton("tank", "tank", "drive", nil, 0.2, 600, 500))
|
table.insert(skeletons, loadSkeleton("tank", "tank", "drive", nil, 0.2, 600, 500))
|
||||||
table.insert(skeletons, loadSkeleton("vine", "vine", "animation", nil, 0.3, 400, 500))
|
table.insert(skeletons, loadSkeleton("vine", "vine", "animation", nil, 0.3, 400, 500))
|
||||||
table.insert(skeletons, loadSkeleton("stretchyman", "stretchyman", "sneak", nil, 0.3, 200, 500))
|
table.insert(skeletons, loadSkeleton("stretchyman", "stretchyman", "sneak", nil, 0.3, 200, 500))
|
||||||
skeletonRenderer = spine.SkeletonRenderer.new()
|
skeletonRenderer = spine.SkeletonRenderer.new()
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.update (delta)
|
function love.update (delta)
|
||||||
-- Update the state with the delta time, apply it, and update the world transforms.
|
-- Update the state with the delta time, apply it, and update the world transforms.
|
||||||
local state = skeletons[activeSkeleton].state
|
local state = skeletons[activeSkeleton].state
|
||||||
local skeleton = skeletons[activeSkeleton].skeleton
|
local skeleton = skeletons[activeSkeleton].skeleton
|
||||||
state:update(delta)
|
state:update(delta)
|
||||||
state:apply(skeleton)
|
state:apply(skeleton)
|
||||||
skeleton:updateWorldTransform()
|
skeleton:updateWorldTransform()
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.draw ()
|
function love.draw ()
|
||||||
love.graphics.setBackgroundColor(128, 128, 128, 255)
|
love.graphics.setBackgroundColor(128, 128, 128, 255)
|
||||||
love.graphics.setColor(255, 255, 255)
|
love.graphics.setColor(255, 255, 255)
|
||||||
local skeleton = skeletons[activeSkeleton].skeleton
|
local skeleton = skeletons[activeSkeleton].skeleton
|
||||||
skeletonRenderer:draw(skeleton)
|
skeletonRenderer:draw(skeleton)
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.mousepressed (x, y, button, istouch)
|
function love.mousepressed (x, y, button, istouch)
|
||||||
activeSkeleton = activeSkeleton + 1
|
activeSkeleton = activeSkeleton + 1
|
||||||
if activeSkeleton > #skeletons then activeSkeleton = 1 end
|
if activeSkeleton > #skeletons then activeSkeleton = 1 end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -27,26 +27,26 @@ cycles.
|
|||||||
|
|
||||||
`state` is an optional table with the following fields:
|
`state` is an optional table with the following fields:
|
||||||
|
|
||||||
- `indent`
|
- `indent`
|
||||||
When `indent` (a boolean) is set, the created string will contain
|
When `indent` (a boolean) is set, the created string will contain
|
||||||
newlines and indentations. Otherwise it will be one long line.
|
newlines and indentations. Otherwise it will be one long line.
|
||||||
- `keyorder`
|
- `keyorder`
|
||||||
`keyorder` is an array to specify the ordering of keys in the
|
`keyorder` is an array to specify the ordering of keys in the
|
||||||
encoded output. If an object has keys which are not in this array
|
encoded output. If an object has keys which are not in this array
|
||||||
they are written after the sorted keys.
|
they are written after the sorted keys.
|
||||||
- `level`
|
- `level`
|
||||||
This is the initial level of indentation used when `indent` is
|
This is the initial level of indentation used when `indent` is
|
||||||
set. For each level two spaces are added. When absent it is set
|
set. For each level two spaces are added. When absent it is set
|
||||||
to 0.
|
to 0.
|
||||||
- `buffer`
|
- `buffer`
|
||||||
`buffer` is an array to store the strings for the result so they
|
`buffer` is an array to store the strings for the result so they
|
||||||
can be concatenated at once. When it isn't given, the encode
|
can be concatenated at once. When it isn't given, the encode
|
||||||
function will create it temporary and will return the
|
function will create it temporary and will return the
|
||||||
concatenated result.
|
concatenated result.
|
||||||
- `bufferlen`
|
- `bufferlen`
|
||||||
When `bufferlen` is set, it has to be the index of the last
|
When `bufferlen` is set, it has to be the index of the last
|
||||||
element of `buffer`.
|
element of `buffer`.
|
||||||
- `tables`
|
- `tables`
|
||||||
`tables` is a set to detect reference cycles. It is created
|
`tables` is a set to detect reference cycles. It is created
|
||||||
temporary when absent. Every table that is currently processed
|
temporary when absent. Every table that is currently processed
|
||||||
is used as key, the value is `true`.
|
is used as key, the value is `true`.
|
||||||
@ -187,9 +187,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
|
|
||||||
<!-- This documentation can be parsed using Markdown to generate HTML.
|
<!-- This documentation can be parsed using Markdown to generate HTML.
|
||||||
The source code is enclosed in a HTML comment so it won't be displayed
|
The source code is enclosed in a HTML comment so it won't be displayed
|
||||||
by browsers, but it should be removed from the final HTML file as
|
by browsers, but it should be removed from the final HTML file as
|
||||||
it isn't a valid HTML comment (and wastes space).
|
it isn't a valid HTML comment (and wastes space).
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!--]==]
|
<!--]==]
|
||||||
@ -245,7 +245,7 @@ end
|
|||||||
|
|
||||||
local escapecodes = {
|
local escapecodes = {
|
||||||
["\""] = "\\\"", ["\\"] = "\\\\", ["\b"] = "\\b", ["\f"] = "\\f",
|
["\""] = "\\\"", ["\\"] = "\\\\", ["\b"] = "\\b", ["\f"] = "\\f",
|
||||||
["\n"] = "\\n", ["\r"] = "\\r", ["\t"] = "\\t"
|
["\n"] = "\\n", ["\r"] = "\\r", ["\t"] = "\\t"
|
||||||
}
|
}
|
||||||
|
|
||||||
local function escapeutf8 (uchar)
|
local function escapeutf8 (uchar)
|
||||||
@ -315,8 +315,7 @@ end
|
|||||||
|
|
||||||
function json.addnewline (state)
|
function json.addnewline (state)
|
||||||
if state.indent then
|
if state.indent then
|
||||||
state.bufferlen = addnewline2 (state.level or 0,
|
state.bufferlen = addnewline2 (state.level or 0, state.buffer, state.bufferlen or #(state.buffer))
|
||||||
state.buffer, state.bufferlen or #(state.buffer))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -452,8 +451,7 @@ function json.encode (value, state)
|
|||||||
state = state or {}
|
state = state or {}
|
||||||
local oldbuffer = state.buffer
|
local oldbuffer = state.buffer
|
||||||
local buffer = oldbuffer or {}
|
local buffer = oldbuffer or {}
|
||||||
local ret, msg = encode2 (value, state.indent, state.level or 0,
|
local ret, msg = encode2 (value, state.indent, state.level or 0, buffer, state.bufferlen or 0, state.tables or {}, state.keyorder)
|
||||||
buffer, state.bufferlen or 0, state.tables or {}, state.keyorder)
|
|
||||||
if not ret then
|
if not ret then
|
||||||
error (msg, 2)
|
error (msg, 2)
|
||||||
elseif oldbuffer then
|
elseif oldbuffer then
|
||||||
@ -705,7 +703,7 @@ function json.use_lpeg ()
|
|||||||
local function UTF16Surrogate (match, pos, high, low)
|
local function UTF16Surrogate (match, pos, high, low)
|
||||||
high, low = tonumber (high, 16), tonumber (low, 16)
|
high, low = tonumber (high, 16), tonumber (low, 16)
|
||||||
if 0xD800 <= high and high <= 0xDBff and 0xDC00 <= low and low <= 0xDFFF then
|
if 0xD800 <= high and high <= 0xDBff and 0xDC00 <= low and low <= 0xDFFF then
|
||||||
return true, unichar ((high - 0xD800) * 0x400 + (low - 0xDC00) + 0x10000)
|
return true, unichar ((high - 0xD800) * 0x400 + (low - 0xDC00) + 0x10000)
|
||||||
else
|
else
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|||||||
@ -91,18 +91,18 @@ function PolygonBatcher.new(vertexCount)
|
|||||||
vertex = { 0, 0, 0, 0, 0, 0, 0, 0 },
|
vertex = { 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||||
indices = nil
|
indices = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
local indices = {}
|
local indices = {}
|
||||||
local i = 1
|
local i = 1
|
||||||
local maxIndicesLength = self.maxIndicesLength
|
local maxIndicesLength = self.maxIndicesLength
|
||||||
while i <= maxIndicesLength do
|
while i <= maxIndicesLength do
|
||||||
indices[i] = 1
|
indices[i] = 1
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
self.indices = indices;
|
self.indices = indices;
|
||||||
|
|
||||||
setmetatable(self, PolygonBatcher)
|
setmetatable(self, PolygonBatcher)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ function PolygonBatcher:draw (texture, vertices, indices)
|
|||||||
local numVertices = #vertices / 8
|
local numVertices = #vertices / 8
|
||||||
local numIndices = #indices
|
local numIndices = #indices
|
||||||
local mesh = self.mesh
|
local mesh = self.mesh
|
||||||
|
|
||||||
if texture ~= self.lastTexture then
|
if texture ~= self.lastTexture then
|
||||||
self:flush()
|
self:flush()
|
||||||
self.lastTexture = texture
|
self.lastTexture = texture
|
||||||
@ -125,7 +125,7 @@ function PolygonBatcher:draw (texture, vertices, indices)
|
|||||||
elseif self.verticesLength + numVertices >= self.maxVerticesLength or self.indicesLength + numIndices > self.maxIndicesLength then
|
elseif self.verticesLength + numVertices >= self.maxVerticesLength or self.indicesLength + numIndices > self.maxIndicesLength then
|
||||||
self:flush()
|
self:flush()
|
||||||
end
|
end
|
||||||
|
|
||||||
local i = 1
|
local i = 1
|
||||||
local indexStart = self.indicesLength + 1
|
local indexStart = self.indicesLength + 1
|
||||||
local offset = self.verticesLength
|
local offset = self.verticesLength
|
||||||
@ -137,7 +137,7 @@ function PolygonBatcher:draw (texture, vertices, indices)
|
|||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
self.indicesLength = self.indicesLength + numIndices
|
self.indicesLength = self.indicesLength + numIndices
|
||||||
|
|
||||||
i = 1
|
i = 1
|
||||||
local vertexStart = self.verticesLength + 1
|
local vertexStart = self.verticesLength + 1
|
||||||
local vertexEnd = vertexStart + numVertices
|
local vertexEnd = vertexStart + numVertices
|
||||||
@ -173,7 +173,7 @@ end
|
|||||||
function PolygonBatcher:stop ()
|
function PolygonBatcher:stop ()
|
||||||
if not self.isDrawing then error("PolygonBatcher is not drawing. Call PolygonBatcher:begin() first.", 2) end
|
if not self.isDrawing then error("PolygonBatcher is not drawing. Call PolygonBatcher:begin() first.", 2) end
|
||||||
if self.verticesLength > 0 then self:flush() end
|
if self.verticesLength > 0 then self:flush() end
|
||||||
|
|
||||||
self.lastTexture = nil
|
self.lastTexture = nil
|
||||||
self.isDrawing = false
|
self.isDrawing = false
|
||||||
end
|
end
|
||||||
@ -195,12 +195,12 @@ end
|
|||||||
function SkeletonRenderer:draw (skeleton)
|
function SkeletonRenderer:draw (skeleton)
|
||||||
local batcher = self.batcher
|
local batcher = self.batcher
|
||||||
local premultipliedAlpha = self.premultipliedAlpha
|
local premultipliedAlpha = self.premultipliedAlpha
|
||||||
|
|
||||||
local lastLoveBlendMode = love.graphics.getBlendMode()
|
local lastLoveBlendMode = love.graphics.getBlendMode()
|
||||||
love.graphics.setBlendMode("alpha")
|
love.graphics.setBlendMode("alpha")
|
||||||
local lastBlendMode = spine.BlendMode.normal
|
local lastBlendMode = spine.BlendMode.normal
|
||||||
batcher:begin()
|
batcher:begin()
|
||||||
|
|
||||||
local drawOrder = skeleton.drawOrder
|
local drawOrder = skeleton.drawOrder
|
||||||
for i, slot in ipairs(drawOrder) do
|
for i, slot in ipairs(drawOrder) do
|
||||||
local attachment = slot.attachment
|
local attachment = slot.attachment
|
||||||
@ -217,7 +217,7 @@ function SkeletonRenderer:draw (skeleton)
|
|||||||
indices = attachment.triangles
|
indices = attachment.triangles
|
||||||
texture = attachment.region.renderObject.texture
|
texture = attachment.region.renderObject.texture
|
||||||
end
|
end
|
||||||
|
|
||||||
if texture then
|
if texture then
|
||||||
local slotBlendMode = slot.data.blendMode
|
local slotBlendMode = slot.data.blendMode
|
||||||
if lastBlendMode ~= slotBlendMode then
|
if lastBlendMode ~= slotBlendMode then
|
||||||
@ -238,7 +238,7 @@ function SkeletonRenderer:draw (skeleton)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
batcher:stop()
|
batcher:stop()
|
||||||
love.graphics.setBlendMode(lastLoveBlendMode)
|
love.graphics.setBlendMode(lastLoveBlendMode)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -69,7 +69,7 @@ function Animation.new (name, timelines, duration)
|
|||||||
|
|
||||||
if loop and duration > 0 then
|
if loop and duration > 0 then
|
||||||
time = time % self.duration
|
time = time % self.duration
|
||||||
if lastTime > 0 then lastTime = lastTime % self.duration end
|
if lastTime > 0 then lastTime = lastTime % self.duration end
|
||||||
end
|
end
|
||||||
|
|
||||||
for i,timeline in ipairs(self.timelines) do
|
for i,timeline in ipairs(self.timelines) do
|
||||||
@ -132,7 +132,7 @@ function Animation.CurveTimeline.new (frameCount)
|
|||||||
local self = {
|
local self = {
|
||||||
curves = utils.newNumberArrayZero((frameCount - 1) * BEZIER_SIZE) -- type, x, y, ...
|
curves = utils.newNumberArrayZero((frameCount - 1) * BEZIER_SIZE) -- type, x, y, ...
|
||||||
}
|
}
|
||||||
|
|
||||||
function self:getFrameCount ()
|
function self:getFrameCount ()
|
||||||
return math.floor(zlen(self.curves) / BEZIER_SIZE) + 1
|
return math.floor(zlen(self.curves) / BEZIER_SIZE) + 1
|
||||||
end
|
end
|
||||||
@ -140,7 +140,7 @@ function Animation.CurveTimeline.new (frameCount)
|
|||||||
function self:setStepped (frameIndex)
|
function self:setStepped (frameIndex)
|
||||||
self.curves[frameIndex * BEZIER_SIZE] = STEPPED
|
self.curves[frameIndex * BEZIER_SIZE] = STEPPED
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:getCurveType (frameIndex)
|
function self:getCurveType (frameIndex)
|
||||||
local index = frameIndex * BEZIER_SIZE
|
local index = frameIndex * BEZIER_SIZE
|
||||||
if index == zlen(self.curves) then return LINEAR end
|
if index == zlen(self.curves) then return LINEAR end
|
||||||
@ -225,7 +225,7 @@ function Animation.RotateTimeline.new (frameCount)
|
|||||||
local self = Animation.CurveTimeline.new(frameCount)
|
local self = Animation.CurveTimeline.new(frameCount)
|
||||||
self.boneIndex = -1
|
self.boneIndex = -1
|
||||||
self.frames = utils.newNumberArrayZero(frameCount * 2)
|
self.frames = utils.newNumberArrayZero(frameCount * 2)
|
||||||
|
|
||||||
function self:setFrame (frameIndex, time, degrees)
|
function self:setFrame (frameIndex, time, degrees)
|
||||||
frameIndex = frameIndex * 2
|
frameIndex = frameIndex * 2
|
||||||
self.frames[frameIndex] = time
|
self.frames[frameIndex] = time
|
||||||
@ -302,7 +302,7 @@ function Animation.TranslateTimeline.new (frameCount)
|
|||||||
if time < frames[0] then return end -- Time is before first frame.
|
if time < frames[0] then return end -- Time is before first frame.
|
||||||
|
|
||||||
local bone = skeleton.bones[self.boneIndex]
|
local bone = skeleton.bones[self.boneIndex]
|
||||||
|
|
||||||
if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
|
if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
|
||||||
bone.x = bone.x + (bone.data.x + frames[zlen(frames) + PREV_X] - bone.x) * alpha
|
bone.x = bone.x + (bone.data.x + frames[zlen(frames) + PREV_X] - bone.x) * alpha
|
||||||
bone.y = bone.y + (bone.data.y + frames[zlen(frames) + PREV_Y] - bone.y) * alpha
|
bone.y = bone.y + (bone.data.y + frames[zlen(frames) + PREV_Y] - bone.y) * alpha
|
||||||
@ -485,7 +485,7 @@ function Animation.AttachmentTimeline.new (frameCount)
|
|||||||
|
|
||||||
function self:apply (skeleton, lastTime, time, firedEvents, alpha)
|
function self:apply (skeleton, lastTime, time, firedEvents, alpha)
|
||||||
local frames = self.frames
|
local frames = self.frames
|
||||||
if time < frames[0] then return end
|
if time < frames[0] then return end
|
||||||
|
|
||||||
local frameIndex = 0
|
local frameIndex = 0
|
||||||
if time >= frames[zlen(frames) - 1] then
|
if time >= frames[zlen(frames) - 1] then
|
||||||
@ -608,7 +608,6 @@ end
|
|||||||
|
|
||||||
Animation.DeformTimeline = {}
|
Animation.DeformTimeline = {}
|
||||||
function Animation.DeformTimeline.new (frameCount)
|
function Animation.DeformTimeline.new (frameCount)
|
||||||
|
|
||||||
local self = Animation.CurveTimeline.new(frameCount)
|
local self = Animation.CurveTimeline.new(frameCount)
|
||||||
self.frames = utils.newNumberArrayZero(frameCount)
|
self.frames = utils.newNumberArrayZero(frameCount)
|
||||||
self.frameVertices = utils.newNumberArrayZero(frameCount)
|
self.frameVertices = utils.newNumberArrayZero(frameCount)
|
||||||
@ -626,7 +625,7 @@ function Animation.DeformTimeline.new (frameCount)
|
|||||||
if not slotAttachment then return end
|
if not slotAttachment then return end
|
||||||
if not (slotAttachment.type == AttachmentType.mesh or slotAttachment.type == AttachmentType.linkedmesh or slotAttachment.type == AttachmentType.path) then return end
|
if not (slotAttachment.type == AttachmentType.mesh or slotAttachment.type == AttachmentType.linkedmesh or slotAttachment.type == AttachmentType.path) then return end
|
||||||
if not slotAttachment:applyDeform(self.attachment) then return end
|
if not slotAttachment:applyDeform(self.attachment) then return end
|
||||||
|
|
||||||
local frames = self.frames
|
local frames = self.frames
|
||||||
if time < frames[0] then return end -- Time is before first frame.
|
if time < frames[0] then return end -- Time is before first frame.
|
||||||
|
|
||||||
@ -761,7 +760,7 @@ function Animation.TransformConstraintTimeline.new (frameCount)
|
|||||||
if time < frames[0] then return end -- Time is before first frame.
|
if time < frames[0] then return end -- Time is before first frame.
|
||||||
|
|
||||||
local constraint = skeleton.transformConstraints[self.transformConstraintIndex]
|
local constraint = skeleton.transformConstraints[self.transformConstraintIndex]
|
||||||
|
|
||||||
if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
|
if time >= frames[zlen(frames) - ENTRIES] then -- Time is after last frame.
|
||||||
local i = zlen(frames)
|
local i = zlen(frames)
|
||||||
constraint.rotateMix = constraintMix.rotateMix + (frames[i + PREV_ROTATE] - constraint.rotateMix) * alpha
|
constraint.rotateMix = constraintMix.rotateMix + (frames[i + PREV_ROTATE] - constraint.rotateMix) * alpha
|
||||||
|
|||||||
@ -141,7 +141,7 @@ function AnimationState.new (data)
|
|||||||
else
|
else
|
||||||
complete = lastTime < endTime and time >= endTime
|
complete = lastTime < endTime and time >= endTime
|
||||||
end
|
end
|
||||||
if complete then
|
if complete then
|
||||||
local count = math.floor(time / endTime)
|
local count = math.floor(time / endTime)
|
||||||
if current.onComplete then current.onComplete(i, count) end
|
if current.onComplete then current.onComplete(i, count) end
|
||||||
if self.onComplete then self.onComplete(i, count) end
|
if self.onComplete then self.onComplete(i, count) end
|
||||||
|
|||||||
@ -45,7 +45,7 @@ function AnimationStateData.new (skeletonData)
|
|||||||
end
|
end
|
||||||
self.animationToMixTime[fromName][toName] = duration
|
self.animationToMixTime[fromName][toName] = duration
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:getMix (fromName, toName)
|
function self:getMix (fromName, toName)
|
||||||
local first = self.animationToMixTime[fromName]
|
local first = self.animationToMixTime[fromName]
|
||||||
if not first then return self.defaultMix end
|
if not first then return self.defaultMix end
|
||||||
|
|||||||
@ -42,11 +42,11 @@ function Atlas.parse(atlasPath, atlasBase)
|
|||||||
local a,b = tonumber( a ), tonumber( b )
|
local a,b = tonumber( a ), tonumber( b )
|
||||||
return a and b and {a, b}
|
return a and b and {a, b}
|
||||||
end
|
end
|
||||||
|
|
||||||
if not atlasPath then
|
if not atlasPath then
|
||||||
error("Error: " .. atlasPath .. ".atlas" .. " doesn't exist!")
|
error("Error: " .. atlasPath .. ".atlas" .. " doesn't exist!")
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local atlasLines = spine.utils.readFile( atlasPath, atlasBase )
|
local atlasLines = spine.utils.readFile( atlasPath, atlasBase )
|
||||||
if not atlasLines then
|
if not atlasLines then
|
||||||
@ -57,7 +57,7 @@ function Atlas.parse(atlasPath, atlasBase)
|
|||||||
local pages = {}
|
local pages = {}
|
||||||
|
|
||||||
|
|
||||||
local it = string.gmatch(atlasLines, "(.-)\r?\n") -- iterate over lines
|
local it = string.gmatch(atlasLines, "(.-)\r?\n") -- iterate over lines
|
||||||
for l in it do
|
for l in it do
|
||||||
if #l == 0 then
|
if #l == 0 then
|
||||||
l = it()
|
l = it()
|
||||||
@ -73,7 +73,7 @@ function Atlas.parse(atlasPath, atlasBase)
|
|||||||
page.wrap = string.match( it(), "%a+: (.+)" )
|
page.wrap = string.match( it(), "%a+: (.+)" )
|
||||||
page.regions = {}
|
page.regions = {}
|
||||||
table.insert( pages, page )
|
table.insert( pages, page )
|
||||||
else
|
else
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|||||||
@ -53,7 +53,7 @@ function AttachmentLoader.new ()
|
|||||||
function self:newBoundingBoxAttachment (skin, name)
|
function self:newBoundingBoxAttachment (skin, name)
|
||||||
return BoundingBoxAttachment.new(name)
|
return BoundingBoxAttachment.new(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
function self:newPathAttachment(skin, name)
|
function self:newPathAttachment(skin, name)
|
||||||
return PathAttachment.new(name)
|
return PathAttachment.new(name)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -37,13 +37,13 @@ local math_atan2 = math.atan2
|
|||||||
local math_sqrt = math.sqrt
|
local math_sqrt = math.sqrt
|
||||||
|
|
||||||
function math.sign(x)
|
function math.sign(x)
|
||||||
if x<0 then
|
if x<0 then
|
||||||
return -1
|
return -1
|
||||||
elseif x>0 then
|
elseif x>0 then
|
||||||
return 1
|
return 1
|
||||||
else
|
else
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local math_sign = math.sign
|
local math_sign = math.sign
|
||||||
@ -84,7 +84,7 @@ end
|
|||||||
|
|
||||||
function Bone:updateWorldTransformWith (x, y, rotation, scaleX, scaleY, shearX, shearY)
|
function Bone:updateWorldTransformWith (x, y, rotation, scaleX, scaleY, shearX, shearY)
|
||||||
self.appliedRotation = rotation
|
self.appliedRotation = rotation
|
||||||
|
|
||||||
local rotationY = rotation + 90 + shearY
|
local rotationY = rotation + 90 + shearY
|
||||||
local rotationRad = math_rad(rotation + shearX)
|
local rotationRad = math_rad(rotation + shearX)
|
||||||
local rotationYRad = math_rad(rotationY)
|
local rotationYRad = math_rad(rotationY)
|
||||||
@ -318,10 +318,10 @@ function updateLocalTransform ()
|
|||||||
self.rotation = 90 - math_deg(math_atan2(rd, rb))
|
self.rotation = 90 - math_deg(math_atan2(rd, rb))
|
||||||
end
|
end
|
||||||
self.appliedRotation = self.rotation
|
self.appliedRotation = self.rotation
|
||||||
end
|
end
|
||||||
|
|
||||||
function Bone:worldToLocal (world)
|
function Bone:worldToLocal (world)
|
||||||
local a = self.a
|
local a = self.a
|
||||||
local b = self.b
|
local b = self.b
|
||||||
local c = self.c
|
local c = self.c
|
||||||
local d = self.d
|
local d = self.d
|
||||||
|
|||||||
@ -39,7 +39,7 @@ function Color.new ()
|
|||||||
r = 0, g = 0, b = 0, a = 0
|
r = 0, g = 0, b = 0, a = 0
|
||||||
}
|
}
|
||||||
setmetatable(self, Color)
|
setmetatable(self, Color)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ function Color.newWith (r, g, b, a)
|
|||||||
r = a, g = g, b = b, a = a
|
r = a, g = g, b = b, a = a
|
||||||
}
|
}
|
||||||
setmetatable(self, Color)
|
setmetatable(self, Color)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -74,9 +74,9 @@ function IkConstraint:update ()
|
|||||||
local target = self.target
|
local target = self.target
|
||||||
local bones = self.bones
|
local bones = self.bones
|
||||||
local boneCount = #bones
|
local boneCount = #bones
|
||||||
if boneCount == 1 then
|
if boneCount == 1 then
|
||||||
self:apply1(bones[1], target.worldX, target.worldY, self.mix)
|
self:apply1(bones[1], target.worldX, target.worldY, self.mix)
|
||||||
elseif boneCount == 2 then
|
elseif boneCount == 2 then
|
||||||
self:apply2(bones[1], bones[2], target.worldX, target.worldY, self.bendDirection, self.mix)
|
self:apply2(bones[1], bones[2], target.worldX, target.worldY, self.bendDirection, self.mix)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -92,7 +92,7 @@ function IkConstraint:apply1 (bone, targetX, targetY, alpha)
|
|||||||
if bone.scaleX < 0 then rotationIK = rotationIK + 180 end
|
if bone.scaleX < 0 then rotationIK = rotationIK + 180 end
|
||||||
if rotationIK > 180 then
|
if rotationIK > 180 then
|
||||||
rotationIK = rotationIK - 360
|
rotationIK = rotationIK - 360
|
||||||
elseif (rotationIK < -180) then
|
elseif (rotationIK < -180) then
|
||||||
rotationIK = rotationIK + 360
|
rotationIK = rotationIK + 360
|
||||||
end
|
end
|
||||||
bone:updateWorldTransformWith(bone.x, bone.y, bone.rotation + rotationIK * alpha, bone.scaleX, bone.scaleY, bone.shearX, bone.shearY)
|
bone:updateWorldTransformWith(bone.x, bone.y, bone.rotation + rotationIK * alpha, bone.scaleX, bone.scaleY, bone.shearX, bone.shearY)
|
||||||
@ -153,7 +153,7 @@ function IkConstraint:apply2 (parent, child, targetX, targetY, bendDir, alpha)
|
|||||||
c = pp.c
|
c = pp.c
|
||||||
d = pp.d
|
d = pp.d
|
||||||
local id = 1 / (a * d - b * c)
|
local id = 1 / (a * d - b * c)
|
||||||
local x = targetX - pp.worldX
|
local x = targetX - pp.worldX
|
||||||
local y = targetY - pp.worldY
|
local y = targetY - pp.worldY
|
||||||
local tx = (x * d - y * b) * id - px
|
local tx = (x * d - y * b) * id - px
|
||||||
local ty = (y * a - x * c) * id - py
|
local ty = (y * a - x * c) * id - py
|
||||||
@ -165,7 +165,7 @@ function IkConstraint:apply2 (parent, child, targetX, targetY, bendDir, alpha)
|
|||||||
local l2 = child.data.length * csx
|
local l2 = child.data.length * csx
|
||||||
local a1 = 0
|
local a1 = 0
|
||||||
local a2 = 0
|
local a2 = 0
|
||||||
|
|
||||||
if u then
|
if u then
|
||||||
l2 = l2 * psx
|
l2 = l2 * psx
|
||||||
local cos = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2)
|
local cos = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2)
|
||||||
@ -269,7 +269,7 @@ function IkConstraint:apply2 (parent, child, targetX, targetY, bendDir, alpha)
|
|||||||
elseif a2 < -180 then
|
elseif a2 < -180 then
|
||||||
a2 = a2 + 360
|
a2 = a2 + 360
|
||||||
end
|
end
|
||||||
child:updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.scaleX, child.scaleY, child.shearX, child.shearY);
|
child:updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.scaleX, child.scaleY, child.shearX, child.shearY);
|
||||||
end
|
end
|
||||||
|
|
||||||
return IkConstraint
|
return IkConstraint
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- FIXME the logic in this file uses 0-based indexing. Each array
|
-- FIXME the logic in this file uses 0-based indexing. Each array
|
||||||
-- access adds 1 to the calculated index. We should switch the logic
|
-- access adds 1 to the calculated index. We should switch the logic
|
||||||
-- to 1-based indexing eventually.
|
-- to 1-based indexing eventually.
|
||||||
|
|
||||||
local setmetatable = setmetatable
|
local setmetatable = setmetatable
|
||||||
@ -76,7 +76,7 @@ function PathConstraint.new (data, skeleton)
|
|||||||
segments = {}
|
segments = {}
|
||||||
}
|
}
|
||||||
setmetatable(self, PathConstraint)
|
setmetatable(self, PathConstraint)
|
||||||
|
|
||||||
for i,boneData in ipairs(data.bones) do
|
for i,boneData in ipairs(data.bones) do
|
||||||
table_insert(self.bones, skeleton:findBone(boneData.name))
|
table_insert(self.bones, skeleton:findBone(boneData.name))
|
||||||
end
|
end
|
||||||
@ -94,7 +94,7 @@ function PathConstraint:update ()
|
|||||||
|
|
||||||
local rotateMix = self.rotateMix
|
local rotateMix = self.rotateMix
|
||||||
local translateMix = self.translateMix
|
local translateMix = self.translateMix
|
||||||
local translate = translateMix > 0
|
local translate = translateMix > 0
|
||||||
local rotate = rotateMix > 0
|
local rotate = rotateMix > 0
|
||||||
if not translate and not rotate then return end
|
if not translate and not rotate then return end
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ function PathConstraint:update ()
|
|||||||
local lengthSpacing = spacingMode == PathConstraintData.SpacingMode.length
|
local lengthSpacing = spacingMode == PathConstraintData.SpacingMode.length
|
||||||
local rotateMode = data.rotateMode
|
local rotateMode = data.rotateMode
|
||||||
local tangents = rotateMode == PathConstraintData.RotateMode.tangent
|
local tangents = rotateMode == PathConstraintData.RotateMode.tangent
|
||||||
local scale = rotateMode == PathConstraintData.RotateMode.chainscale
|
local scale = rotateMode == PathConstraintData.RotateMode.chainscale
|
||||||
local bones = self.bones
|
local bones = self.bones
|
||||||
local boneCount = #bones
|
local boneCount = #bones
|
||||||
local spacesCount = boneCount + 1
|
local spacesCount = boneCount + 1
|
||||||
@ -281,7 +281,7 @@ function PathConstraint:computeWorldPositions (path, spacesCount, tangents, perc
|
|||||||
end
|
end
|
||||||
self:addCurvePosition(p, world[1], world[2], world[3], world[4], world[5], world[6], world[7], world[8], out, o, tangents or (i > 0 and space == 0))
|
self:addCurvePosition(p, world[1], world[2], world[3], world[4], world[5], world[6], world[7], world[8], out, o, tangents or (i > 0 and space == 0))
|
||||||
end
|
end
|
||||||
|
|
||||||
i = i + 1
|
i = i + 1
|
||||||
o = o + 3
|
o = o + 3
|
||||||
end
|
end
|
||||||
@ -360,7 +360,7 @@ function PathConstraint:computeWorldPositions (path, spacesCount, tangents, perc
|
|||||||
if percentPosition then position = position * pathLength end
|
if percentPosition then position = position * pathLength end
|
||||||
if percentSpacing then
|
if percentSpacing then
|
||||||
local i = 0
|
local i = 0
|
||||||
while i < spacesCount do
|
while i < spacesCount do
|
||||||
spaces[i + 1] = spaces[i + 1] * pathLength
|
spaces[i + 1] = spaces[i + 1] * pathLength
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
|
|||||||
@ -33,7 +33,7 @@ local AttachmentType = require "spine-lua.AttachmentType"
|
|||||||
local RegionAttachment = {}
|
local RegionAttachment = {}
|
||||||
function RegionAttachment.new (name)
|
function RegionAttachment.new (name)
|
||||||
if not name then error("name cannot be nil", 2) end
|
if not name then error("name cannot be nil", 2) end
|
||||||
|
|
||||||
local self = {
|
local self = {
|
||||||
name = name,
|
name = name,
|
||||||
type = AttachmentType.region,
|
type = AttachmentType.region,
|
||||||
|
|||||||
@ -88,15 +88,15 @@ function Skeleton.new (data)
|
|||||||
for i,ikConstraintData in ipairs(data.ikConstraints) do
|
for i,ikConstraintData in ipairs(data.ikConstraints) do
|
||||||
table_insert(self.ikConstraints, IkConstraint.new(ikConstraintData, self))
|
table_insert(self.ikConstraints, IkConstraint.new(ikConstraintData, self))
|
||||||
end
|
end
|
||||||
|
|
||||||
for i, transformConstraintData in ipairs(data.transformConstraints) do
|
for i, transformConstraintData in ipairs(data.transformConstraints) do
|
||||||
table_insert(self.transformConstraints, TransformConstraint.new(transformConstraintData, self))
|
table_insert(self.transformConstraints, TransformConstraint.new(transformConstraintData, self))
|
||||||
end
|
end
|
||||||
|
|
||||||
for i, pathConstraintData in ipairs(data.pathConstraints) do
|
for i, pathConstraintData in ipairs(data.pathConstraints) do
|
||||||
table_insert(self.pathConstraints, PathConstraint.new(pathConstraintData, self))
|
table_insert(self.pathConstraints, PathConstraint.new(pathConstraintData, self))
|
||||||
end
|
end
|
||||||
|
|
||||||
self:updateCache()
|
self:updateCache()
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@ -107,18 +107,18 @@ end
|
|||||||
function Skeleton:updateCache ()
|
function Skeleton:updateCache ()
|
||||||
local updateCache = {}
|
local updateCache = {}
|
||||||
self._updateCache = updateCache
|
self._updateCache = updateCache
|
||||||
|
|
||||||
local bones = self.bones
|
local bones = self.bones
|
||||||
for i, bone in ipairs(bones) do
|
for i, bone in ipairs(bones) do
|
||||||
bone.sorted = false
|
bone.sorted = false
|
||||||
end
|
end
|
||||||
|
|
||||||
local ikConstraints = {}
|
local ikConstraints = {}
|
||||||
self.ikConstraintsSorted = ikConstraints
|
self.ikConstraintsSorted = ikConstraints
|
||||||
for i, constraint in ipairs(self.ikConstraints) do
|
for i, constraint in ipairs(self.ikConstraints) do
|
||||||
table_insert(ikConstraints, constraint)
|
table_insert(ikConstraints, constraint)
|
||||||
end
|
end
|
||||||
|
|
||||||
local level = 0
|
local level = 0
|
||||||
for i, ik in ipairs(ikConstraints) do
|
for i, ik in ipairs(ikConstraints) do
|
||||||
local bone = ik.bones[1].parent
|
local bone = ik.bones[1].parent
|
||||||
@ -129,7 +129,7 @@ function Skeleton:updateCache ()
|
|||||||
end
|
end
|
||||||
ik.level = level
|
ik.level = level
|
||||||
end
|
end
|
||||||
|
|
||||||
local i = 1
|
local i = 1
|
||||||
local ikCount = #ikConstraints
|
local ikCount = #ikConstraints
|
||||||
while i < ikCount do
|
while i < ikCount do
|
||||||
@ -145,19 +145,19 @@ function Skeleton:updateCache ()
|
|||||||
ikConstraints[ii + 1 + 1] = ik
|
ikConstraints[ii + 1 + 1] = ik
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
for i, constraint in ipairs(ikConstraints) do
|
for i, constraint in ipairs(ikConstraints) do
|
||||||
local target = constraint.target
|
local target = constraint.target
|
||||||
self:sortBone(target)
|
self:sortBone(target)
|
||||||
|
|
||||||
local constrained = constraint.bones
|
local constrained = constraint.bones
|
||||||
local parent = constrained[1]
|
local parent = constrained[1]
|
||||||
self:sortBone(parent)
|
self:sortBone(parent)
|
||||||
|
|
||||||
table_insert(updateCache, constraint)
|
table_insert(updateCache, constraint)
|
||||||
|
|
||||||
self:sortReset(parent.children)
|
self:sortReset(parent.children)
|
||||||
constrained[#constrained].sorted = true
|
constrained[#constrained].sorted = true
|
||||||
end
|
end
|
||||||
|
|
||||||
-- path constraints
|
-- path constraints
|
||||||
@ -169,19 +169,19 @@ function Skeleton:updateCache ()
|
|||||||
if self.skin then self:sortPathConstraintAttachment(self.skin, slotIndex, slotBone) end
|
if self.skin then self:sortPathConstraintAttachment(self.skin, slotIndex, slotBone) end
|
||||||
if self.data.defaultSkin and self.data.defaultSkin ~= self.skin then self:sortPathConstraintAttachment(self.data.defaultSkin, slotIndex, slotBone) end
|
if self.data.defaultSkin and self.data.defaultSkin ~= self.skin then self:sortPathConstraintAttachment(self.data.defaultSkin, slotIndex, slotBone) end
|
||||||
for i,skin in ipairs(self.data.skins) do
|
for i,skin in ipairs(self.data.skins) do
|
||||||
self:sortPathConstraintAttachment(skin, slotIndex, slotBone)
|
self:sortPathConstraintAttachment(skin, slotIndex, slotBone)
|
||||||
end
|
end
|
||||||
|
|
||||||
local attachment = slot.attachment
|
local attachment = slot.attachment
|
||||||
if attachment.type == AttachmentType.path then self:sortPathConstraintAttachmentWith(attachment, slotBone) end
|
if attachment.type == AttachmentType.path then self:sortPathConstraintAttachmentWith(attachment, slotBone) end
|
||||||
|
|
||||||
local constrained = constraint.bones
|
local constrained = constraint.bones
|
||||||
for i,c in ipairs(constrained) do
|
for i,c in ipairs(constrained) do
|
||||||
self:sortBone(c)
|
self:sortBone(c)
|
||||||
end
|
end
|
||||||
|
|
||||||
table_insert(updateCache, constraint)
|
table_insert(updateCache, constraint)
|
||||||
|
|
||||||
for i,c in ipairs(constrained) do
|
for i,c in ipairs(constrained) do
|
||||||
self:sortReset(c.children)
|
self:sortReset(c.children)
|
||||||
end
|
end
|
||||||
@ -189,19 +189,19 @@ function Skeleton:updateCache ()
|
|||||||
c.sorted = true
|
c.sorted = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- transform constraints
|
-- transform constraints
|
||||||
local transformConstraints = self.transformConstraints
|
local transformConstraints = self.transformConstraints
|
||||||
for i, constraint in ipairs(transformConstraints) do
|
for i, constraint in ipairs(transformConstraints) do
|
||||||
self:sortBone(constraint.target)
|
self:sortBone(constraint.target)
|
||||||
|
|
||||||
local constrained = constraint.bones
|
local constrained = constraint.bones
|
||||||
for i,c in ipairs(constrained) do
|
for i,c in ipairs(constrained) do
|
||||||
self:sortBone(c)
|
self:sortBone(c)
|
||||||
end
|
end
|
||||||
|
|
||||||
table_insert(updateCache, constraint)
|
table_insert(updateCache, constraint)
|
||||||
|
|
||||||
for i,c in ipairs(constrained) do
|
for i,c in ipairs(constrained) do
|
||||||
self:sortReset(c.children)
|
self:sortReset(c.children)
|
||||||
end
|
end
|
||||||
@ -209,7 +209,7 @@ function Skeleton:updateCache ()
|
|||||||
c.sorted = true
|
c.sorted = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for i, bone in ipairs(self.bones) do
|
for i, bone in ipairs(self.bones) do
|
||||||
self:sortBone(bone)
|
self:sortBone(bone)
|
||||||
end
|
end
|
||||||
@ -281,7 +281,7 @@ function Skeleton:setBonesToSetupPose ()
|
|||||||
ikConstraint.bendDirection = ikConstraint.data.bendDirection
|
ikConstraint.bendDirection = ikConstraint.data.bendDirection
|
||||||
ikConstraint.mix = ikConstraint.data.mix
|
ikConstraint.mix = ikConstraint.data.mix
|
||||||
end
|
end
|
||||||
|
|
||||||
local transformConstraints = self.transformConstraints
|
local transformConstraints = self.transformConstraints
|
||||||
for i, constraint in ipairs(transformConstraints) do
|
for i, constraint in ipairs(transformConstraints) do
|
||||||
local data = constraint.data
|
local data = constraint.data
|
||||||
@ -290,7 +290,7 @@ function Skeleton:setBonesToSetupPose ()
|
|||||||
constraint.scaleMix = data.scaleMix
|
constraint.scaleMix = data.scaleMix
|
||||||
constraint.shearMix = data.shearMix
|
constraint.shearMix = data.shearMix
|
||||||
end
|
end
|
||||||
|
|
||||||
local pathConstraints = self.pathConstraints
|
local pathConstraints = self.pathConstraints
|
||||||
for i, constraint in ipairs(pathConstraints) do
|
for i, constraint in ipairs(pathConstraints) do
|
||||||
local data = constraint.data
|
local data = constraint.data
|
||||||
@ -341,8 +341,8 @@ function Skeleton:findSlotIndex(slotName)
|
|||||||
return -1
|
return -1
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Sets the skin used to look up attachments before looking in the {@link SkeletonData#getDefaultSkin() default skin}.
|
-- Sets the skin used to look up attachments before looking in the {@link SkeletonData#getDefaultSkin() default skin}.
|
||||||
-- Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was
|
-- Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was
|
||||||
-- no old skin, each slot's setup mode attachment is attached from the new skin.
|
-- no old skin, each slot's setup mode attachment is attached from the new skin.
|
||||||
function Skeleton:setSkin (skinName)
|
function Skeleton:setSkin (skinName)
|
||||||
local skin = self.data:findSkin(skinName)
|
local skin = self.data:findSkin(skinName)
|
||||||
|
|||||||
@ -65,7 +65,7 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
local readAnimation
|
local readAnimation
|
||||||
local readCurve
|
local readCurve
|
||||||
local getArray
|
local getArray
|
||||||
|
|
||||||
local getValue = function (map, name, default)
|
local getValue = function (map, name, default)
|
||||||
local value = map[name]
|
local value = map[name]
|
||||||
if value == nil then return default else return value end
|
if value == nil then return default else return value end
|
||||||
@ -90,7 +90,7 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
-- Bones.
|
-- Bones.
|
||||||
for i,boneMap in ipairs(root["bones"]) do
|
for i,boneMap in ipairs(root["bones"]) do
|
||||||
local boneName = boneMap["name"]
|
local boneName = boneMap["name"]
|
||||||
|
|
||||||
local parent = nil
|
local parent = nil
|
||||||
local parentName = boneMap["parent"]
|
local parentName = boneMap["parent"]
|
||||||
if parentName then
|
if parentName then
|
||||||
@ -108,10 +108,10 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
data.shearY = getValue(boneMap, "shearY", 0);
|
data.shearY = getValue(boneMap, "shearY", 0);
|
||||||
data.inheritRotation = getValue(boneMap, "inheritRotation", true);
|
data.inheritRotation = getValue(boneMap, "inheritRotation", true);
|
||||||
data.inheritScale = getValue(boneMap, "inheritScale", true);
|
data.inheritScale = getValue(boneMap, "inheritScale", true);
|
||||||
|
|
||||||
table_insert(skeletonData.bones, data)
|
table_insert(skeletonData.bones, data)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Slots.
|
-- Slots.
|
||||||
if root["slots"] then
|
if root["slots"] then
|
||||||
for i,slotMap in ipairs(root["slots"]) do
|
for i,slotMap in ipairs(root["slots"]) do
|
||||||
@ -124,10 +124,10 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
|
|
||||||
local color = slotMap["color"]
|
local color = slotMap["color"]
|
||||||
if color then
|
if color then
|
||||||
data.color:set(tonumber(color:sub(1, 2), 16) / 255,
|
data.color:set(tonumber(color:sub(1, 2), 16) / 255,
|
||||||
tonumber(color:sub(3, 4), 16) / 255,
|
tonumber(color:sub(3, 4), 16) / 255,
|
||||||
tonumber(color:sub(5, 6), 16) / 255,
|
tonumber(color:sub(5, 6), 16) / 255,
|
||||||
tonumber(color:sub(7, 8), 16) / 255)
|
tonumber(color:sub(7, 8), 16) / 255)
|
||||||
end
|
end
|
||||||
|
|
||||||
data.attachmentName = getValue(slotMap, "attachment", nil)
|
data.attachmentName = getValue(slotMap, "attachment", nil)
|
||||||
@ -159,22 +159,22 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
table_insert(skeletonData.ikConstraints, data)
|
table_insert(skeletonData.ikConstraints, data)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Transform constraints
|
-- Transform constraints
|
||||||
if root["transform"] then
|
if root["transform"] then
|
||||||
for i,constraintMap in ipairs(root["transform"]) do
|
for i,constraintMap in ipairs(root["transform"]) do
|
||||||
data = TransformConstraintData.new(constraintMap.name)
|
data = TransformConstraintData.new(constraintMap.name)
|
||||||
|
|
||||||
for i,boneName in ipairs(constraintMap.bones) do
|
for i,boneName in ipairs(constraintMap.bones) do
|
||||||
local bone = skeletonData:findBone(boneName)
|
local bone = skeletonData:findBone(boneName)
|
||||||
if not bone then error("Transform constraint bone not found: " .. boneName, 2) end
|
if not bone then error("Transform constraint bone not found: " .. boneName, 2) end
|
||||||
table_insert(data.bones, bone)
|
table_insert(data.bones, bone)
|
||||||
end
|
end
|
||||||
|
|
||||||
local targetName = constraintMap.target
|
local targetName = constraintMap.target
|
||||||
data.target = skeletonData:findBone(targetName)
|
data.target = skeletonData:findBone(targetName)
|
||||||
if not data.target then error("Transform constraint target bone not found: " .. boneName, 2) end
|
if not data.target then error("Transform constraint target bone not found: " .. boneName, 2) end
|
||||||
|
|
||||||
data.offsetRotation = getValue(constraintMap, "rotation", 0);
|
data.offsetRotation = getValue(constraintMap, "rotation", 0);
|
||||||
data.offsetX = getValue(constraintMap, "x", 0) * scale;
|
data.offsetX = getValue(constraintMap, "x", 0) * scale;
|
||||||
data.offsetY = getValue(constraintMap, "y", 0) * scale;
|
data.offsetY = getValue(constraintMap, "y", 0) * scale;
|
||||||
@ -190,7 +190,7 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
table_insert(skeletonData.transformConstraints, data)
|
table_insert(skeletonData.transformConstraints, data)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Path constraints
|
-- Path constraints
|
||||||
if root["path"] then
|
if root["path"] then
|
||||||
for i,constraintMap in ipairs(root.path) do
|
for i,constraintMap in ipairs(root.path) do
|
||||||
@ -238,7 +238,7 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
if skin.name == "default" then skeletonData.defaultSkin = skin end
|
if skin.name == "default" then skeletonData.defaultSkin = skin end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Linked meshes
|
-- Linked meshes
|
||||||
for i, linkedMesh in ipairs(self.linkedMeshes) do
|
for i, linkedMesh in ipairs(self.linkedMeshes) do
|
||||||
local skin = skeletonData.defaultSkin
|
local skin = skeletonData.defaultSkin
|
||||||
@ -290,44 +290,44 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
region.rotation = getValue(map, "rotation", 0);
|
region.rotation = getValue(map, "rotation", 0);
|
||||||
region.width = map.width * scale;
|
region.width = map.width * scale;
|
||||||
region.height = map.height * scale;
|
region.height = map.height * scale;
|
||||||
|
|
||||||
local color = map["color"]
|
local color = map["color"]
|
||||||
if color then
|
if color then
|
||||||
region.color:set(tonumber(color:sub(1, 2), 16) / 255,
|
region.color:set(tonumber(color:sub(1, 2), 16) / 255,
|
||||||
tonumber(color:sub(3, 4), 16) / 255,
|
tonumber(color:sub(3, 4), 16) / 255,
|
||||||
tonumber(color:sub(5, 6), 16) / 255,
|
tonumber(color:sub(5, 6), 16) / 255,
|
||||||
tonumber(color:sub(7, 8), 16) / 255)
|
tonumber(color:sub(7, 8), 16) / 255)
|
||||||
end
|
end
|
||||||
|
|
||||||
region:updateOffset()
|
region:updateOffset()
|
||||||
return region
|
return region
|
||||||
|
|
||||||
elseif type == AttachmentType.boundingbox then
|
elseif type == AttachmentType.boundingbox then
|
||||||
local box = attachmentLoader:newBoundingBoxAttachment(skin, name)
|
local box = attachmentLoader:newBoundingBoxAttachment(skin, name)
|
||||||
if not box then return nil end
|
if not box then return nil end
|
||||||
readVertices(map, box, map.vertexCount * 2)
|
readVertices(map, box, map.vertexCount * 2)
|
||||||
local color = map.color
|
local color = map.color
|
||||||
if color then
|
if color then
|
||||||
box.color:set(tonumber(color:sub(1, 2), 16) / 255,
|
box.color:set(tonumber(color:sub(1, 2), 16) / 255,
|
||||||
tonumber(color:sub(3, 4), 16) / 255,
|
tonumber(color:sub(3, 4), 16) / 255,
|
||||||
tonumber(color:sub(5, 6), 16) / 255,
|
tonumber(color:sub(5, 6), 16) / 255,
|
||||||
tonumber(color:sub(7, 8), 16) / 255)
|
tonumber(color:sub(7, 8), 16) / 255)
|
||||||
end
|
end
|
||||||
return box
|
return box
|
||||||
|
|
||||||
elseif type == AttachmentType.mesh or type == AttachmentType.linkedmesh then
|
elseif type == AttachmentType.mesh or type == AttachmentType.linkedmesh then
|
||||||
local mesh = attachmentLoader:newMeshAttachment(skin, name, path)
|
local mesh = attachmentLoader:newMeshAttachment(skin, name, path)
|
||||||
if not mesh then return null end
|
if not mesh then return null end
|
||||||
mesh.path = path
|
mesh.path = path
|
||||||
|
|
||||||
local color = map.color
|
local color = map.color
|
||||||
if color then
|
if color then
|
||||||
mesh.color:set(tonumber(color:sub(1, 2), 16) / 255,
|
mesh.color:set(tonumber(color:sub(1, 2), 16) / 255,
|
||||||
tonumber(color:sub(3, 4), 16) / 255,
|
tonumber(color:sub(3, 4), 16) / 255,
|
||||||
tonumber(color:sub(5, 6), 16) / 255,
|
tonumber(color:sub(5, 6), 16) / 255,
|
||||||
tonumber(color:sub(7, 8), 16) / 255)
|
tonumber(color:sub(7, 8), 16) / 255)
|
||||||
end
|
end
|
||||||
|
|
||||||
local parent = map.parent
|
local parent = map.parent
|
||||||
if parent then
|
if parent then
|
||||||
mesh.inheritDeform = getValue(map, "deform", true)
|
mesh.inheritDeform = getValue(map, "deform", true)
|
||||||
@ -339,7 +339,7 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
})
|
})
|
||||||
return mesh
|
return mesh
|
||||||
end
|
end
|
||||||
|
|
||||||
local uvs = getArray(map, "uvs", 1)
|
local uvs = getArray(map, "uvs", 1)
|
||||||
readVertices(map, mesh, #uvs)
|
readVertices(map, mesh, #uvs)
|
||||||
mesh.triangles = getArray(map, "triangles", 1)
|
mesh.triangles = getArray(map, "triangles", 1)
|
||||||
@ -352,7 +352,7 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
|
|
||||||
mesh.hullLength = getValue(map, "hull", 0) * 2
|
mesh.hullLength = getValue(map, "hull", 0) * 2
|
||||||
return mesh
|
return mesh
|
||||||
|
|
||||||
elseif type == AttachmentType.path then
|
elseif type == AttachmentType.path then
|
||||||
local path = self.attachmentLoader:newPathAttachment(skin, name)
|
local path = self.attachmentLoader:newPathAttachment(skin, name)
|
||||||
if not path then return nil end
|
if not path then return nil end
|
||||||
@ -370,17 +370,17 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
|
|
||||||
local color = map.color
|
local color = map.color
|
||||||
if color then
|
if color then
|
||||||
path.color:set(tonumber(color:sub(1, 2), 16) / 255,
|
path.color:set(tonumber(color:sub(1, 2), 16) / 255,
|
||||||
tonumber(color:sub(3, 4), 16) / 255,
|
tonumber(color:sub(3, 4), 16) / 255,
|
||||||
tonumber(color:sub(5, 6), 16) / 255,
|
tonumber(color:sub(5, 6), 16) / 255,
|
||||||
tonumber(color:sub(7, 8), 16) / 255)
|
tonumber(color:sub(7, 8), 16) / 255)
|
||||||
end
|
end
|
||||||
return path;
|
return path;
|
||||||
end
|
end
|
||||||
|
|
||||||
error("Unknown attachment type: " .. type .. " (" .. name .. ")")
|
error("Unknown attachment type: " .. type .. " (" .. name .. ")")
|
||||||
end
|
end
|
||||||
|
|
||||||
readVertices = function (map, attachment, verticesLength)
|
readVertices = function (map, attachment, verticesLength)
|
||||||
local scale = self.scale
|
local scale = self.scale
|
||||||
attachment.worldVerticesLength = verticesLength
|
attachment.worldVerticesLength = verticesLength
|
||||||
@ -397,7 +397,7 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
attachment.vertices = vertices
|
attachment.vertices = vertices
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local weights = {}
|
local weights = {}
|
||||||
local bones = {}
|
local bones = {}
|
||||||
local i = 0
|
local i = 0
|
||||||
@ -439,7 +439,7 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
for i,valueMap in ipairs(values) do
|
for i,valueMap in ipairs(values) do
|
||||||
local color = valueMap["color"]
|
local color = valueMap["color"]
|
||||||
timeline:setFrame(
|
timeline:setFrame(
|
||||||
frameIndex, valueMap["time"],
|
frameIndex, valueMap["time"],
|
||||||
tonumber(color:sub(1, 2), 16) / 255,
|
tonumber(color:sub(1, 2), 16) / 255,
|
||||||
tonumber(color:sub(3, 4), 16) / 255,
|
tonumber(color:sub(3, 4), 16) / 255,
|
||||||
tonumber(color:sub(5, 6), 16) / 255,
|
tonumber(color:sub(5, 6), 16) / 255,
|
||||||
@ -548,7 +548,7 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
duration = math.max(duration, timeline.frames[(timeline:getFrameCount() - 1) * Animation.IkConstraintTimeline.ENTRIES])
|
duration = math.max(duration, timeline.frames[(timeline:getFrameCount() - 1) * Animation.IkConstraintTimeline.ENTRIES])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Transform constraint timelines.
|
-- Transform constraint timelines.
|
||||||
local transform = map["transform"]
|
local transform = map["transform"]
|
||||||
if transform then
|
if transform then
|
||||||
@ -562,8 +562,8 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
local frameIndex = 0
|
local frameIndex = 0
|
||||||
for i,valueMap in ipairs(values) do
|
for i,valueMap in ipairs(values) do
|
||||||
timeline:setFrame(frameIndex, valueMap.time, getValue(valueMap, "rotateMix", 1), getValue(valueMap, "translateMix", 1), getValue(valueMap, "scaleMix", 1), getValue(valueMap, "shearMix", 1))
|
timeline:setFrame(frameIndex, valueMap.time, getValue(valueMap, "rotateMix", 1), getValue(valueMap, "translateMix", 1), getValue(valueMap, "scaleMix", 1) getValue(valueMap, "shearMix", 1))
|
||||||
readCurve(valueMap, timeline, frameIndex)
|
readCurve(valueMap, timeline, frameIndex)
|
||||||
frameIndex = frameIndex + 1
|
frameIndex = frameIndex + 1
|
||||||
end
|
end
|
||||||
@ -571,7 +571,7 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
duration = math.max(duration, timeline.frames[(timeline:getFrameCount() - 1) * Animation.TransformConstraintTimeline.ENTRIES])
|
duration = math.max(duration, timeline.frames[(timeline:getFrameCount() - 1) * Animation.TransformConstraintTimeline.ENTRIES])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Path constraint timelines.
|
-- Path constraint timelines.
|
||||||
if map.paths then
|
if map.paths then
|
||||||
for constraintName,constraintMap in pairs(map.paths) do
|
for constraintName,constraintMap in pairs(map.paths) do
|
||||||
@ -587,7 +587,7 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
if data.spacingMode == PathConstraintData.SpacingMode.length or data.spacingMode == PathConstraintData.SpacingMode.fixed then timelineScale = scale end
|
if data.spacingMode == PathConstraintData.SpacingMode.length or data.spacingMode == PathConstraintData.SpacingMode.fixed then timelineScale = scale end
|
||||||
else
|
else
|
||||||
timeline = Animation.PathConstraintPositionTimeline.new(#timelineMap)
|
timeline = Animation.PathConstraintPositionTimeline.new(#timelineMap)
|
||||||
if data.positionMode == PathConstraintData.PositionMode.fixed then timelineScale = scale end
|
if data.positionMode == PathConstraintData.PositionMode.fixed then timelineScale = scale end
|
||||||
end
|
end
|
||||||
timeline.pathConstraintIndex = index
|
timeline.pathConstraintIndex = index
|
||||||
local frameIndex = 0
|
local frameIndex = 0
|
||||||
@ -609,11 +609,11 @@ function SkeletonJson.new (attachmentLoader)
|
|||||||
end
|
end
|
||||||
table_insert(timelines, timeline)
|
table_insert(timelines, timeline)
|
||||||
duration = math.max(duration, timeline.frames[(timeline:getFrameCount() - 1) * Animation.PathConstraintMixTimeline.ENTRIES])
|
duration = math.max(duration, timeline.frames[(timeline:getFrameCount() - 1) * Animation.PathConstraintMixTimeline.ENTRIES])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Deform timelines.
|
-- Deform timelines.
|
||||||
if map.deform then
|
if map.deform then
|
||||||
for deformName, deformMap in pairs(map.deform) do
|
for deformName, deformMap in pairs(map.deform) do
|
||||||
|
|||||||
@ -36,7 +36,7 @@ Skin.__index = Skin
|
|||||||
|
|
||||||
function Skin.new (name)
|
function Skin.new (name)
|
||||||
if not name then error("name cannot be nil", 2) end
|
if not name then error("name cannot be nil", 2) end
|
||||||
|
|
||||||
local self = {
|
local self = {
|
||||||
name = name,
|
name = name,
|
||||||
attachments = {}
|
attachments = {}
|
||||||
@ -55,7 +55,7 @@ end
|
|||||||
function Skin:getAttachment (slotIndex, name)
|
function Skin:getAttachment (slotIndex, name)
|
||||||
if not name then error("name cannot be nil.", 2) end
|
if not name then error("name cannot be nil.", 2) end
|
||||||
local dictionary = self.attachments[slotIndex]
|
local dictionary = self.attachments[slotIndex]
|
||||||
if dictionary then
|
if dictionary then
|
||||||
return dictionary[name]
|
return dictionary[name]
|
||||||
else
|
else
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -40,7 +40,7 @@ function SlotData.new (index, name, boneData)
|
|||||||
if index < 0 then error("index must be >= 0", 2) end
|
if index < 0 then error("index must be >= 0", 2) end
|
||||||
if not name then error("name cannot be nil", 2) end
|
if not name then error("name cannot be nil", 2) end
|
||||||
if not boneData then error("boneData cannot be nil", 2) end
|
if not boneData then error("boneData cannot be nil", 2) end
|
||||||
|
|
||||||
local self = {
|
local self = {
|
||||||
index = index,
|
index = index,
|
||||||
name = name,
|
name = name,
|
||||||
@ -50,7 +50,7 @@ function SlotData.new (index, name, boneData)
|
|||||||
blendMode = BlendMode.normal
|
blendMode = BlendMode.normal
|
||||||
}
|
}
|
||||||
setmetatable(self, SlotData)
|
setmetatable(self, SlotData)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -64,38 +64,38 @@ function TextureAtlas.new (atlasContent, imageLoader)
|
|||||||
regions = {}
|
regions = {}
|
||||||
}
|
}
|
||||||
setmetatable(self, TextureAtlas)
|
setmetatable(self, TextureAtlas)
|
||||||
|
|
||||||
self:parse(atlasContent, imageLoader)
|
self:parse(atlasContent, imageLoader)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function TextureAtlas:parse (atlasContent, imageLoader)
|
function TextureAtlas:parse (atlasContent, imageLoader)
|
||||||
if not atlasContent then error("atlasContent cannot be nil.", 2) end
|
if not atlasContent then error("atlasContent cannot be nil.", 2) end
|
||||||
if not imageLoader then error("imageLoader cannot be nil.", 2) end
|
if not imageLoader then error("imageLoader cannot be nil.", 2) end
|
||||||
|
|
||||||
local lines = {}
|
local lines = {}
|
||||||
local index = 0
|
local index = 0
|
||||||
local numLines = 0
|
local numLines = 0
|
||||||
for line in atlasContent:gmatch("[^\r\n]+") do
|
for line in atlasContent:gmatch("[^\r\n]+") do
|
||||||
lines[numLines] = line
|
lines[numLines] = line
|
||||||
numLines = numLines + 1
|
numLines = numLines + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
local readLine = function ()
|
local readLine = function ()
|
||||||
if index >= numLines then return nil end
|
if index >= numLines then return nil end
|
||||||
local line = lines[index]
|
local line = lines[index]
|
||||||
index = index + 1
|
index = index + 1
|
||||||
return line
|
return line
|
||||||
end
|
end
|
||||||
|
|
||||||
local readValue = function ()
|
local readValue = function ()
|
||||||
local line = readLine()
|
local line = readLine()
|
||||||
local idx = line:find(":")
|
local idx = line:find(":")
|
||||||
if not idx then error("Invalid line: " .. line, 2) end
|
if not idx then error("Invalid line: " .. line, 2) end
|
||||||
return line:sub(idx + 1):match'^%s*(.*%S)' or ''
|
return line:sub(idx + 1):match'^%s*(.*%S)' or ''
|
||||||
end
|
end
|
||||||
|
|
||||||
local readTuple = function ()
|
local readTuple = function ()
|
||||||
local line = readLine()
|
local line = readLine()
|
||||||
local idx = line:find(":")
|
local idx = line:find(":")
|
||||||
@ -113,11 +113,11 @@ function TextureAtlas:parse (atlasContent, imageLoader)
|
|||||||
tuple[i] = line:sub(lastMatch):match'^%s*(.*%S)' or ''
|
tuple[i] = line:sub(lastMatch):match'^%s*(.*%S)' or ''
|
||||||
return tuple
|
return tuple
|
||||||
end
|
end
|
||||||
|
|
||||||
local parseInt = function (str)
|
local parseInt = function (str)
|
||||||
return tonumber(str)
|
return tonumber(str)
|
||||||
end
|
end
|
||||||
|
|
||||||
local filterFromString = function (str)
|
local filterFromString = function (str)
|
||||||
str = str:lower()
|
str = str:lower()
|
||||||
if str == "nearest" then return TextureFilter.Nearest
|
if str == "nearest" then return TextureFilter.Nearest
|
||||||
@ -130,18 +130,18 @@ function TextureAtlas:parse (atlasContent, imageLoader)
|
|||||||
else error("Unknown texture wrap: " .. str, 2)
|
else error("Unknown texture wrap: " .. str, 2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local page = nil
|
local page = nil
|
||||||
while true do
|
while true do
|
||||||
local line = readLine()
|
local line = readLine()
|
||||||
if not line then break end
|
if not line then break end
|
||||||
line = line:match'^%s*(.*%S)' or ''
|
line = line:match'^%s*(.*%S)' or ''
|
||||||
if line:len() == 0 then
|
if line:len() == 0 then
|
||||||
page = nil
|
page = nil
|
||||||
elseif not page then
|
elseif not page then
|
||||||
page = TextureAtlasPage.new()
|
page = TextureAtlasPage.new()
|
||||||
page.name = line
|
page.name = line
|
||||||
|
|
||||||
local tuple = readTuple()
|
local tuple = readTuple()
|
||||||
if #tuple == 2 then
|
if #tuple == 2 then
|
||||||
page.width = parseInt(tuple[1])
|
page.width = parseInt(tuple[1])
|
||||||
@ -153,11 +153,11 @@ function TextureAtlas:parse (atlasContent, imageLoader)
|
|||||||
-- wrapper objects for images to get the page size from
|
-- wrapper objects for images to get the page size from
|
||||||
error("Atlas must specify page width/height. Please export to the latest atlas format", 2)
|
error("Atlas must specify page width/height. Please export to the latest atlas format", 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
tuple = readTuple()
|
tuple = readTuple()
|
||||||
page.minFilter = filterFromString(tuple[1])
|
page.minFilter = filterFromString(tuple[1])
|
||||||
page.magFilter = filterFromString(tuple[2])
|
page.magFilter = filterFromString(tuple[2])
|
||||||
|
|
||||||
local direction = readValue()
|
local direction = readValue()
|
||||||
page.uWrap = TextureWrap.ClampToEdge
|
page.uWrap = TextureWrap.ClampToEdge
|
||||||
page.vWrap = TextureWrap.ClampToEdge
|
page.vWrap = TextureWrap.ClampToEdge
|
||||||
@ -169,7 +169,7 @@ function TextureAtlas:parse (atlasContent, imageLoader)
|
|||||||
page.uWrap = TextureWrap.Repeat
|
page.uWrap = TextureWrap.Repeat
|
||||||
page.vWrap = TextureWrap.Repeat
|
page.vWrap = TextureWrap.Repeat
|
||||||
end
|
end
|
||||||
|
|
||||||
page.texture = imageLoader(line)
|
page.texture = imageLoader(line)
|
||||||
-- FIXME page.texture:setFilters(page.minFilter, page.magFilter)
|
-- FIXME page.texture:setFilters(page.minFilter, page.magFilter)
|
||||||
-- FIXME page.texture:setWraps(page.uWrap, page.vWrap)
|
-- FIXME page.texture:setWraps(page.uWrap, page.vWrap)
|
||||||
@ -178,17 +178,17 @@ function TextureAtlas:parse (atlasContent, imageLoader)
|
|||||||
local region = TextureAtlasRegion.new()
|
local region = TextureAtlasRegion.new()
|
||||||
region.name = line
|
region.name = line
|
||||||
region.page = page
|
region.page = page
|
||||||
|
|
||||||
if readValue() == "true" then region.rotate = true end
|
if readValue() == "true" then region.rotate = true end
|
||||||
|
|
||||||
local tuple = readTuple()
|
local tuple = readTuple()
|
||||||
local x = parseInt(tuple[1])
|
local x = parseInt(tuple[1])
|
||||||
local y = parseInt(tuple[2])
|
local y = parseInt(tuple[2])
|
||||||
|
|
||||||
tuple = readTuple()
|
tuple = readTuple()
|
||||||
local width = parseInt(tuple[1])
|
local width = parseInt(tuple[1])
|
||||||
local height = parseInt(tuple[2])
|
local height = parseInt(tuple[2])
|
||||||
|
|
||||||
region.u = x / page.width
|
region.u = x / page.width
|
||||||
region.v = y / page.height
|
region.v = y / page.height
|
||||||
if region.rotate then
|
if region.rotate then
|
||||||
@ -198,12 +198,12 @@ function TextureAtlas:parse (atlasContent, imageLoader)
|
|||||||
region.u2 = (x + width) / page.width
|
region.u2 = (x + width) / page.width
|
||||||
region.v2 = (y + height) / page.height
|
region.v2 = (y + height) / page.height
|
||||||
end
|
end
|
||||||
|
|
||||||
region.x = x
|
region.x = x
|
||||||
region.y = y
|
region.y = y
|
||||||
region.width = math_abs(width)
|
region.width = math_abs(width)
|
||||||
region.height = math_abs(height)
|
region.height = math_abs(height)
|
||||||
|
|
||||||
-- Read and skip optional splits
|
-- Read and skip optional splits
|
||||||
tuple = readTuple()
|
tuple = readTuple()
|
||||||
if #tuple == 4 then
|
if #tuple == 4 then
|
||||||
@ -212,14 +212,14 @@ function TextureAtlas:parse (atlasContent, imageLoader)
|
|||||||
readTuple()
|
readTuple()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
region.originalWidth = parseInt(tuple[1])
|
region.originalWidth = parseInt(tuple[1])
|
||||||
region.originalHeight = parseInt(tuple[2])
|
region.originalHeight = parseInt(tuple[2])
|
||||||
|
|
||||||
tuple = readTuple()
|
tuple = readTuple()
|
||||||
region.offsetX = parseInt(tuple[1])
|
region.offsetX = parseInt(tuple[1])
|
||||||
region.offsetY = parseInt(tuple[2])
|
region.offsetY = parseInt(tuple[2])
|
||||||
|
|
||||||
region.index = parseInt(readValue())
|
region.index = parseInt(readValue())
|
||||||
region.texture = page.texture
|
region.texture = page.texture
|
||||||
table_insert(self.regions, region)
|
table_insert(self.regions, region)
|
||||||
|
|||||||
@ -46,7 +46,7 @@ function TextureAtlasRegion.new ()
|
|||||||
self.rotate = false
|
self.rotate = false
|
||||||
self.texture = nil
|
self.texture = nil
|
||||||
setmetatable(self, TextureAtlasRegion)
|
setmetatable(self, TextureAtlasRegion)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -45,7 +45,7 @@ function TextureRegion.new ()
|
|||||||
originalWidth = 0, originalHeight = 0
|
originalWidth = 0, originalHeight = 0
|
||||||
}
|
}
|
||||||
setmetatable(self, TextureRegion)
|
setmetatable(self, TextureRegion)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -56,7 +56,7 @@ function TransformConstraint.new (data, skeleton)
|
|||||||
temp = { 0, 0 }
|
temp = { 0, 0 }
|
||||||
}
|
}
|
||||||
setmetatable(self, TransformConstraint)
|
setmetatable(self, TransformConstraint)
|
||||||
|
|
||||||
for i,bone in ipairs(data.bones) do
|
for i,bone in ipairs(data.bones) do
|
||||||
table_insert(self.bones, skeleton:findBone(bone.name))
|
table_insert(self.bones, skeleton:findBone(bone.name))
|
||||||
end
|
end
|
||||||
@ -77,7 +77,7 @@ function TransformConstraint:update ()
|
|||||||
local target = self.target
|
local target = self.target
|
||||||
local ta = target.a
|
local ta = target.a
|
||||||
local tb = target.b
|
local tb = target.b
|
||||||
local tc = target.c
|
local tc = target.c
|
||||||
local td = target.d
|
local td = target.d
|
||||||
local bones = self.bones
|
local bones = self.bones
|
||||||
for i, bone in ipairs(bones) do
|
for i, bone in ipairs(bones) do
|
||||||
|
|||||||
@ -36,15 +36,15 @@ local Attachment = {}
|
|||||||
Attachment.__index = Attachment
|
Attachment.__index = Attachment
|
||||||
|
|
||||||
function Attachment.new (name, attachmentType)
|
function Attachment.new (name, attachmentType)
|
||||||
if not name then error("name cannot be nil.", 2) end
|
if not name then error("name cannot be nil.", 2) end
|
||||||
if not attachmentType then error("attachmentType cannot be nil.", 2) end
|
if not attachmentType then error("attachmentType cannot be nil.", 2) end
|
||||||
|
|
||||||
local self = {
|
local self = {
|
||||||
name = name,
|
name = name,
|
||||||
type = attachmentType
|
type = attachmentType
|
||||||
}
|
}
|
||||||
setmetatable(self, Attachment)
|
setmetatable(self, Attachment)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
return Attachment
|
return Attachment
|
||||||
|
|||||||
@ -32,7 +32,7 @@ local AttachmentType = {
|
|||||||
region = 0,
|
region = 0,
|
||||||
boundingbox = 1,
|
boundingbox = 1,
|
||||||
mesh = 2,
|
mesh = 2,
|
||||||
linkedmesh = 3,
|
linkedmesh = 3,
|
||||||
path = 4
|
path = 4
|
||||||
}
|
}
|
||||||
return AttachmentType
|
return AttachmentType
|
||||||
|
|||||||
@ -40,8 +40,8 @@ function BoundingBoxAttachment.new (name)
|
|||||||
if not name then error("name cannot be nil", 2) end
|
if not name then error("name cannot be nil", 2) end
|
||||||
|
|
||||||
local self = VertexAttachment.new(name, AttachmentType.boundingbox)
|
local self = VertexAttachment.new(name, AttachmentType.boundingbox)
|
||||||
self.color = Color.newWith(1, 1, 1, 1)
|
self.color = Color.newWith(1, 1, 1, 1)
|
||||||
setmetatable(self, BoundingBoxAttachment)
|
setmetatable(self, BoundingBoxAttachment)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
return BoundingBoxAttachment
|
return BoundingBoxAttachment
|
||||||
|
|||||||
@ -42,191 +42,191 @@ function MeshAttachment.new (name)
|
|||||||
if not name then error("name cannot be nil", 2) end
|
if not name then error("name cannot be nil", 2) end
|
||||||
|
|
||||||
local self = VertexAttachment.new(name, AttachmentType.mesh)
|
local self = VertexAttachment.new(name, AttachmentType.mesh)
|
||||||
self.region = nil
|
self.region = nil
|
||||||
self.path = nil
|
self.path = nil
|
||||||
self.regionUVs = nil
|
self.regionUVs = nil
|
||||||
self.worldVertices = nil
|
self.worldVertices = nil
|
||||||
self.triangles = nil
|
self.triangles = nil
|
||||||
self.color = Color.newWith(1, 1, 1, 1)
|
self.color = Color.newWith(1, 1, 1, 1)
|
||||||
self.hullLength = 0
|
self.hullLength = 0
|
||||||
self.parentMesh = nil
|
self.parentMesh = nil
|
||||||
self.inheritDeform = false
|
self.inheritDeform = false
|
||||||
self.tempColor = Color.newWith(1, 1, 1, 1)
|
self.tempColor = Color.newWith(1, 1, 1, 1)
|
||||||
setmetatable(self, MeshAttachment)
|
setmetatable(self, MeshAttachment)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function MeshAttachment:updateUVs ()
|
function MeshAttachment:updateUVs ()
|
||||||
local regionUVs = self.regionUVs
|
local regionUVs = self.regionUVs
|
||||||
local verticesLength = #regionUVs
|
local verticesLength = #regionUVs
|
||||||
local worldVerticesLength = (verticesLength / 2) * 8
|
local worldVerticesLength = (verticesLength / 2) * 8
|
||||||
if not self.worldVertices or #self.worldVertices ~= worldVerticesLength then
|
if not self.worldVertices or #self.worldVertices ~= worldVerticesLength then
|
||||||
self.worldVertices = utils.newNumberArray(worldVerticesLength)
|
self.worldVertices = utils.newNumberArray(worldVerticesLength)
|
||||||
end
|
end
|
||||||
|
|
||||||
local u = 0
|
local u = 0
|
||||||
local v = 0
|
local v = 0
|
||||||
local width = 0
|
local width = 0
|
||||||
local height = 0
|
local height = 0
|
||||||
if not self.region then
|
if not self.region then
|
||||||
u = 0
|
u = 0
|
||||||
v = 0
|
v = 0
|
||||||
width = 1
|
width = 1
|
||||||
height = 1
|
height = 1
|
||||||
else
|
else
|
||||||
u = self.region.u;
|
u = self.region.u;
|
||||||
v = self.region.v;
|
v = self.region.v;
|
||||||
width = self.region.u2 - u;
|
width = self.region.u2 - u;
|
||||||
height = self.region.v2 - v;
|
height = self.region.v2 - v;
|
||||||
end
|
end
|
||||||
if self.region and self.region.rotate then
|
if self.region and self.region.rotate then
|
||||||
local i = 0
|
local i = 0
|
||||||
local w = 2
|
local w = 2
|
||||||
while i < verticesLength do
|
while i < verticesLength do
|
||||||
self.worldVertices[w + 1] = u + regionUVs[i + 2] * width;
|
self.worldVertices[w + 1] = u + regionUVs[i + 2] * width;
|
||||||
self.worldVertices[w + 2] = v + height - regionUVs[i + 1] * height;
|
self.worldVertices[w + 2] = v + height - regionUVs[i + 1] * height;
|
||||||
i = i + 2
|
i = i + 2
|
||||||
w = w + 8
|
w = w + 8
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local i = 0
|
local i = 0
|
||||||
local w = 2
|
local w = 2
|
||||||
while i < verticesLength do
|
while i < verticesLength do
|
||||||
self.worldVertices[w + 1] = u + regionUVs[i + 1] * width;
|
self.worldVertices[w + 1] = u + regionUVs[i + 1] * width;
|
||||||
self.worldVertices[w + 2] = v + regionUVs[i + 2] * height;
|
self.worldVertices[w + 2] = v + regionUVs[i + 2] * height;
|
||||||
i = i + 2
|
i = i + 2
|
||||||
w = w + 8
|
w = w + 8
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function MeshAttachment:updateWorldVertices(slot, premultipliedAlpha)
|
function MeshAttachment:updateWorldVertices(slot, premultipliedAlpha)
|
||||||
local skeleton = slot.bone.skeleton
|
local skeleton = slot.bone.skeleton
|
||||||
local skeletonColor = skeleton.color
|
local skeletonColor = skeleton.color
|
||||||
local slotColor = slot.color
|
local slotColor = slot.color
|
||||||
local meshColor = self.color
|
local meshColor = self.color
|
||||||
|
|
||||||
local alpha = skeletonColor.a * slotColor.a * meshColor.a
|
|
||||||
local multiplier = 1
|
|
||||||
if premultipliedAlpha then multiplier = alpha end
|
|
||||||
local color = self.tempColor
|
|
||||||
color:set(skeletonColor.r * slotColor.r * meshColor.r * multiplier,
|
|
||||||
skeletonColor.g * slotColor.g * meshColor.g * multiplier,
|
|
||||||
skeletonColor.b * slotColor.b * meshColor.b * multiplier,
|
|
||||||
alpha)
|
|
||||||
|
|
||||||
local x = skeleton.x
|
local alpha = skeletonColor.a * slotColor.a * meshColor.a
|
||||||
local y = skeleton.y
|
local multiplier = 1
|
||||||
local deformArray = slot.attachmentVertices
|
if premultipliedAlpha then multiplier = alpha end
|
||||||
local vertices = self.vertices
|
local color = self.tempColor
|
||||||
local worldVertices = self.worldVertices
|
color:set(skeletonColor.r * slotColor.r * meshColor.r * multiplier,
|
||||||
local bones = self.bones
|
skeletonColor.g * slotColor.g * meshColor.g * multiplier,
|
||||||
if not bones then
|
skeletonColor.b * slotColor.b * meshColor.b * multiplier,
|
||||||
local verticesLength = #vertices
|
alpha)
|
||||||
if #deformArray > 0 then vertices = deformArray end
|
|
||||||
local bone = slot.bone;
|
local x = skeleton.x
|
||||||
x = x + bone.worldX
|
local y = skeleton.y
|
||||||
y = y + bone.worldY
|
local deformArray = slot.attachmentVertices
|
||||||
local a = bone.a
|
local vertices = self.vertices
|
||||||
local b = bone.b
|
local worldVertices = self.worldVertices
|
||||||
local c = bone.c
|
local bones = self.bones
|
||||||
local d = bone.d
|
if not bones then
|
||||||
local v = 0
|
local verticesLength = #vertices
|
||||||
local w = 0
|
if #deformArray > 0 then vertices = deformArray end
|
||||||
while v < verticesLength do
|
local bone = slot.bone;
|
||||||
local vx = vertices[v + 1]
|
x = x + bone.worldX
|
||||||
local vy = vertices[v + 2]
|
y = y + bone.worldY
|
||||||
worldVertices[w + 1] = vx * a + vy * b + x
|
local a = bone.a
|
||||||
worldVertices[w + 2] = vx * c + vy * d + y
|
local b = bone.b
|
||||||
worldVertices[w + 5] = color.r
|
local c = bone.c
|
||||||
worldVertices[w + 6] = color.g
|
local d = bone.d
|
||||||
worldVertices[w + 7] = color.b
|
local v = 0
|
||||||
worldVertices[w + 8] = color.a
|
local w = 0
|
||||||
v = v + 2
|
while v < verticesLength do
|
||||||
w = w + 8
|
local vx = vertices[v + 1]
|
||||||
end
|
local vy = vertices[v + 2]
|
||||||
return worldVertices
|
worldVertices[w + 1] = vx * a + vy * b + x
|
||||||
end
|
worldVertices[w + 2] = vx * c + vy * d + y
|
||||||
|
worldVertices[w + 5] = color.r
|
||||||
local skeletonBones = skeleton.bones
|
worldVertices[w + 6] = color.g
|
||||||
if #deformArray == 0 then
|
worldVertices[w + 7] = color.b
|
||||||
local w = 0
|
worldVertices[w + 8] = color.a
|
||||||
local v = 0
|
v = v + 2
|
||||||
local b = 0
|
w = w + 8
|
||||||
local n = #bones
|
end
|
||||||
while v < n do
|
return worldVertices
|
||||||
local wx = x
|
end
|
||||||
local wy = y
|
|
||||||
local nn = bones[v + 1];
|
local skeletonBones = skeleton.bones
|
||||||
v = v + 1
|
if #deformArray == 0 then
|
||||||
nn = nn + v
|
local w = 0
|
||||||
while v < nn do
|
local v = 0
|
||||||
local bone = skeletonBones[bones[v + 1]];
|
local b = 0
|
||||||
local vx = vertices[b + 1]
|
local n = #bones
|
||||||
local vy = vertices[b + 2]
|
while v < n do
|
||||||
local weight = vertices[b + 3]
|
local wx = x
|
||||||
wx = wx + (vx * bone.a + vy * bone.b + bone.worldX) * weight
|
local wy = y
|
||||||
wy = wy + (vx * bone.c + vy * bone.d + bone.worldY) * weight
|
local nn = bones[v + 1];
|
||||||
v = v + 1
|
v = v + 1
|
||||||
b = b + 3
|
nn = nn + v
|
||||||
end
|
while v < nn do
|
||||||
worldVertices[w + 1] = wx
|
local bone = skeletonBones[bones[v + 1]];
|
||||||
worldVertices[w + 2] = wy
|
local vx = vertices[b + 1]
|
||||||
worldVertices[w + 5] = color.r
|
local vy = vertices[b + 2]
|
||||||
worldVertices[w + 6] = color.g
|
local weight = vertices[b + 3]
|
||||||
worldVertices[w + 7] = color.b
|
wx = wx + (vx * bone.a + vy * bone.b + bone.worldX) * weight
|
||||||
worldVertices[w + 8] = color.a
|
wy = wy + (vx * bone.c + vy * bone.d + bone.worldY) * weight
|
||||||
w = w + 8
|
v = v + 1
|
||||||
end
|
b = b + 3
|
||||||
else
|
end
|
||||||
local deform = deformArray;
|
worldVertices[w + 1] = wx
|
||||||
local w = 0
|
worldVertices[w + 2] = wy
|
||||||
local v = 0
|
worldVertices[w + 5] = color.r
|
||||||
local b = 0
|
worldVertices[w + 6] = color.g
|
||||||
local f = 0
|
worldVertices[w + 7] = color.b
|
||||||
local n = #bones
|
worldVertices[w + 8] = color.a
|
||||||
while v < n do
|
w = w + 8
|
||||||
local wx = x
|
end
|
||||||
local wy = y
|
else
|
||||||
local nn = bones[v + 1]
|
local deform = deformArray;
|
||||||
v = v + 1
|
local w = 0
|
||||||
nn = nn + v
|
local v = 0
|
||||||
while v < nn do
|
local b = 0
|
||||||
local bone = skeletonBones[bones[v + 1]];
|
local f = 0
|
||||||
local vx = vertices[b + 1] + deform[f + 1]
|
local n = #bones
|
||||||
local vy = vertices[b + 2] + deform[f + 2]
|
while v < n do
|
||||||
local weight = vertices[b + 3]
|
local wx = x
|
||||||
wx = wx + (vx * bone.a + vy * bone.b + bone.worldX) * weight
|
local wy = y
|
||||||
wy = wy + (vx * bone.c + vy * bone.d + bone.worldY) * weight
|
local nn = bones[v + 1]
|
||||||
b = b + 3
|
v = v + 1
|
||||||
f = f + 2
|
nn = nn + v
|
||||||
v = v + 1
|
while v < nn do
|
||||||
end
|
local bone = skeletonBones[bones[v + 1]];
|
||||||
worldVertices[w + 1] = wx;
|
local vx = vertices[b + 1] + deform[f + 1]
|
||||||
worldVertices[w + 2] = wy;
|
local vy = vertices[b + 2] + deform[f + 2]
|
||||||
worldVertices[w + 5] = color.r;
|
local weight = vertices[b + 3]
|
||||||
worldVertices[w + 6] = color.g;
|
wx = wx + (vx * bone.a + vy * bone.b + bone.worldX) * weight
|
||||||
worldVertices[w + 7] = color.b;
|
wy = wy + (vx * bone.c + vy * bone.d + bone.worldY) * weight
|
||||||
worldVertices[w + 8] = color.a;
|
b = b + 3
|
||||||
w = w + 8
|
f = f + 2
|
||||||
end
|
v = v + 1
|
||||||
end
|
end
|
||||||
return worldVertices;
|
worldVertices[w + 1] = wx;
|
||||||
|
worldVertices[w + 2] = wy;
|
||||||
|
worldVertices[w + 5] = color.r;
|
||||||
|
worldVertices[w + 6] = color.g;
|
||||||
|
worldVertices[w + 7] = color.b;
|
||||||
|
worldVertices[w + 8] = color.a;
|
||||||
|
w = w + 8
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return worldVertices;
|
||||||
end
|
end
|
||||||
|
|
||||||
function MeshAttachment:applyDeform (sourceAttachment)
|
function MeshAttachment:applyDeform (sourceAttachment)
|
||||||
return self == sourceAttachment or (self.inheritDeform and self.parentMesh == sourceAttachment)
|
return self == sourceAttachment or (self.inheritDeform and self.parentMesh == sourceAttachment)
|
||||||
end
|
end
|
||||||
|
|
||||||
function MeshAttachment:setParentMesh (parentMesh)
|
function MeshAttachment:setParentMesh (parentMesh)
|
||||||
self.parentMesh = parentMesh
|
self.parentMesh = parentMesh
|
||||||
if parentMesh then
|
if parentMesh then
|
||||||
self.bones = parentMesh.bones
|
self.bones = parentMesh.bones
|
||||||
self.vertices = parentMesh.vertices
|
self.vertices = parentMesh.vertices
|
||||||
self.regionUVs = parentMesh.regionUVs
|
self.regionUVs = parentMesh.regionUVs
|
||||||
self.triangles = parentMesh.triangles
|
self.triangles = parentMesh.triangles
|
||||||
self.hullLength = parentMesh.hullLength
|
self.hullLength = parentMesh.hullLength
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return MeshAttachment
|
return MeshAttachment
|
||||||
|
|||||||
@ -40,9 +40,9 @@ function PathAttachment.new (name)
|
|||||||
if not name then error("name cannot be nil", 2) end
|
if not name then error("name cannot be nil", 2) end
|
||||||
|
|
||||||
local self = VertexAttachment.new(name, AttachmentType.path)
|
local self = VertexAttachment.new(name, AttachmentType.path)
|
||||||
self.lengths = nil
|
self.lengths = nil
|
||||||
self.color = Color.newWith(1, 1, 1, 1)
|
self.color = Color.newWith(1, 1, 1, 1)
|
||||||
setmetatable(self, PathAttachment)
|
setmetatable(self, PathAttachment)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
return PathAttachment
|
return PathAttachment
|
||||||
|
|||||||
@ -89,142 +89,142 @@ setmetatable(RegionAttachment, { __index = Attachment })
|
|||||||
|
|
||||||
function RegionAttachment.new (name)
|
function RegionAttachment.new (name)
|
||||||
if not name then error("name cannot be nil", 2) end
|
if not name then error("name cannot be nil", 2) end
|
||||||
|
|
||||||
local self = Attachment.new(name, AttachmentType.region)
|
local self = Attachment.new(name, AttachmentType.region)
|
||||||
self.x = 0
|
self.x = 0
|
||||||
self.y = 0
|
self.y = 0
|
||||||
self.scaleX = 1
|
self.scaleX = 1
|
||||||
self.scaleY = 1
|
self.scaleY = 1
|
||||||
self.rotation = 0
|
self.rotation = 0
|
||||||
self.width = 0
|
self.width = 0
|
||||||
self.height = 0
|
self.height = 0
|
||||||
self.color = Color.newWith(1, 1, 1, 1)
|
self.color = Color.newWith(1, 1, 1, 1)
|
||||||
self.path = nil
|
self.path = nil
|
||||||
self.rendererObject = nil
|
self.rendererObject = nil
|
||||||
self.region = nil
|
self.region = nil
|
||||||
self.offset = Utils.newNumberArray(8)
|
self.offset = Utils.newNumberArray(8)
|
||||||
self.vertices = Utils.newNumberArray(8 * 4)
|
self.vertices = Utils.newNumberArray(8 * 4)
|
||||||
self.tempColor = Color.newWith(1, 1, 1, 1)
|
self.tempColor = Color.newWith(1, 1, 1, 1)
|
||||||
setmetatable(self, RegionAttachment)
|
setmetatable(self, RegionAttachment)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function RegionAttachment:setRegion (region)
|
function RegionAttachment:setRegion (region)
|
||||||
local vertices = self.vertices
|
local vertices = self.vertices
|
||||||
if region.rotate then
|
if region.rotate then
|
||||||
vertices[U2] = region.u
|
vertices[U2] = region.u
|
||||||
vertices[V2] = region.v2
|
vertices[V2] = region.v2
|
||||||
vertices[U3] = region.u
|
vertices[U3] = region.u
|
||||||
vertices[V3] = region.v
|
vertices[V3] = region.v
|
||||||
vertices[U4] = region.u2
|
vertices[U4] = region.u2
|
||||||
vertices[V4] = region.v
|
vertices[V4] = region.v
|
||||||
vertices[U1] = region.u2
|
vertices[U1] = region.u2
|
||||||
vertices[V1] = region.v2
|
vertices[V1] = region.v2
|
||||||
else
|
else
|
||||||
vertices[U1] = region.u
|
vertices[U1] = region.u
|
||||||
vertices[V1] = region.v2
|
vertices[V1] = region.v2
|
||||||
vertices[U2] = region.u
|
vertices[U2] = region.u
|
||||||
vertices[V2] = region.v
|
vertices[V2] = region.v
|
||||||
vertices[U3] = region.u2
|
vertices[U3] = region.u2
|
||||||
vertices[V3] = region.v
|
vertices[V3] = region.v
|
||||||
vertices[U4] = region.u2
|
vertices[U4] = region.u2
|
||||||
vertices[V4] = region.v2
|
vertices[V4] = region.v2
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function RegionAttachment:updateOffset ()
|
function RegionAttachment:updateOffset ()
|
||||||
local regionScaleX = self.width / self.region.originalWidth * self.scaleX
|
local regionScaleX = self.width / self.region.originalWidth * self.scaleX
|
||||||
local regionScaleY = self.height / self.region.originalHeight * self.scaleY
|
local regionScaleY = self.height / self.region.originalHeight * self.scaleY
|
||||||
local localX = -self.width / 2 * self.scaleX + self.region.offsetX * regionScaleX
|
local localX = -self.width / 2 * self.scaleX + self.region.offsetX * regionScaleX
|
||||||
local localY = -self.height / 2 * self.scaleY + self.region.offsetY * regionScaleY
|
local localY = -self.height / 2 * self.scaleY + self.region.offsetY * regionScaleY
|
||||||
local localX2 = localX + self.region.width * regionScaleX
|
local localX2 = localX + self.region.width * regionScaleX
|
||||||
local localY2 = localY + self.region.height * regionScaleY
|
local localY2 = localY + self.region.height * regionScaleY
|
||||||
local radians = self.rotation * math_pi / 180
|
local radians = self.rotation * math_pi / 180
|
||||||
local cos = math_cos(radians)
|
local cos = math_cos(radians)
|
||||||
local sin = math_sin(radians)
|
local sin = math_sin(radians)
|
||||||
local localXCos = localX * cos + self.x
|
local localXCos = localX * cos + self.x
|
||||||
local localXSin = localX * sin
|
local localXSin = localX * sin
|
||||||
local localYCos = localY * cos + self.y
|
local localYCos = localY * cos + self.y
|
||||||
local localYSin = localY * sin
|
local localYSin = localY * sin
|
||||||
local localX2Cos = localX2 * cos + self.x
|
local localX2Cos = localX2 * cos + self.x
|
||||||
local localX2Sin = localX2 * sin
|
local localX2Sin = localX2 * sin
|
||||||
local localY2Cos = localY2 * cos + self.y
|
local localY2Cos = localY2 * cos + self.y
|
||||||
local localY2Sin = localY2 * sin
|
local localY2Sin = localY2 * sin
|
||||||
local offset = self.offset
|
local offset = self.offset
|
||||||
offset[OX1] = localXCos - localYSin
|
offset[OX1] = localXCos - localYSin
|
||||||
offset[OY1] = localYCos + localXSin
|
offset[OY1] = localYCos + localXSin
|
||||||
offset[OX2] = localXCos - localY2Sin
|
offset[OX2] = localXCos - localY2Sin
|
||||||
offset[OY2] = localY2Cos + localXSin
|
offset[OY2] = localY2Cos + localXSin
|
||||||
offset[OX3] = localX2Cos - localY2Sin
|
offset[OX3] = localX2Cos - localY2Sin
|
||||||
offset[OY3] = localY2Cos + localX2Sin
|
offset[OY3] = localY2Cos + localX2Sin
|
||||||
offset[OX4] = localX2Cos - localYSin
|
offset[OX4] = localX2Cos - localYSin
|
||||||
offset[OY4] = localYCos + localX2Sin
|
offset[OY4] = localYCos + localX2Sin
|
||||||
end
|
end
|
||||||
|
|
||||||
function RegionAttachment:updateWorldVertices (slot, premultipliedAlpha)
|
function RegionAttachment:updateWorldVertices (slot, premultipliedAlpha)
|
||||||
local skeleton = slot.bone.skeleton
|
local skeleton = slot.bone.skeleton
|
||||||
local skeletonColor = skeleton.color
|
local skeletonColor = skeleton.color
|
||||||
local slotColor = slot.color
|
local slotColor = slot.color
|
||||||
local regionColor = self.color
|
local regionColor = self.color
|
||||||
local alpha = skeletonColor.a * slotColor.a * regionColor.a
|
local alpha = skeletonColor.a * slotColor.a * regionColor.a
|
||||||
local multiplier = alpha
|
local multiplier = alpha
|
||||||
if premultipliedAlpha then multiplier = 1 end
|
if premultipliedAlpha then multiplier = 1 end
|
||||||
local color = self.tempColor
|
local color = self.tempColor
|
||||||
color:set(skeletonColor.r * slotColor.r * regionColor.r * multiplier,
|
color:set(skeletonColor.r * slotColor.r * regionColor.r * multiplier,
|
||||||
skeletonColor.g * slotColor.g * regionColor.g * multiplier,
|
skeletonColor.g * slotColor.g * regionColor.g * multiplier,
|
||||||
skeletonColor.b * slotColor.b * regionColor.b * multiplier,
|
skeletonColor.b * slotColor.b * regionColor.b * multiplier,
|
||||||
alpha)
|
alpha)
|
||||||
|
|
||||||
local vertices = self.vertices
|
local vertices = self.vertices
|
||||||
local offset = self.offset
|
local offset = self.offset
|
||||||
local bone = slot.bone
|
local bone = slot.bone
|
||||||
local x = skeleton.x + bone.worldX
|
local x = skeleton.x + bone.worldX
|
||||||
local y = skeleton.y + bone.worldY
|
local y = skeleton.y + bone.worldY
|
||||||
local a = bone.a
|
local a = bone.a
|
||||||
local b = bone.b
|
local b = bone.b
|
||||||
local c = bone.c
|
local c = bone.c
|
||||||
local d = bone.d
|
local d = bone.d
|
||||||
local offsetX = 0
|
local offsetX = 0
|
||||||
local offsetY = 0
|
local offsetY = 0
|
||||||
|
|
||||||
offsetX = offset[OX1]
|
offsetX = offset[OX1]
|
||||||
offsetY = offset[OY1]
|
offsetY = offset[OY1]
|
||||||
vertices[X1] = offsetX * a + offsetY * b + x -- br
|
vertices[X1] = offsetX * a + offsetY * b + x -- br
|
||||||
vertices[Y1] = offsetX * c + offsetY * d + y
|
vertices[Y1] = offsetX * c + offsetY * d + y
|
||||||
vertices[C1R] = color.r
|
vertices[C1R] = color.r
|
||||||
vertices[C1G] = color.g
|
vertices[C1G] = color.g
|
||||||
vertices[C1B] = color.b
|
vertices[C1B] = color.b
|
||||||
vertices[C1A] = color.a
|
vertices[C1A] = color.a
|
||||||
|
|
||||||
offsetX = offset[OX2]
|
offsetX = offset[OX2]
|
||||||
offsetY = offset[OY2]
|
offsetY = offset[OY2]
|
||||||
vertices[X2] = offsetX * a + offsetY * b + x -- bl
|
vertices[X2] = offsetX * a + offsetY * b + x -- bl
|
||||||
vertices[Y2] = offsetX * c + offsetY * d + y
|
vertices[Y2] = offsetX * c + offsetY * d + y
|
||||||
vertices[C2R] = color.r
|
vertices[C2R] = color.r
|
||||||
vertices[C2G] = color.g
|
vertices[C2G] = color.g
|
||||||
vertices[C2B] = color.b
|
vertices[C2B] = color.b
|
||||||
vertices[C2A] = color.a
|
vertices[C2A] = color.a
|
||||||
|
|
||||||
offsetX = offset[OX3]
|
offsetX = offset[OX3]
|
||||||
offsetY = offset[OY3]
|
offsetY = offset[OY3]
|
||||||
vertices[X3] = offsetX * a + offsetY * b + x -- ul
|
vertices[X3] = offsetX * a + offsetY * b + x -- ul
|
||||||
vertices[Y3] = offsetX * c + offsetY * d + y
|
vertices[Y3] = offsetX * c + offsetY * d + y
|
||||||
vertices[C3R] = color.r
|
vertices[C3R] = color.r
|
||||||
vertices[C3G] = color.g
|
vertices[C3G] = color.g
|
||||||
vertices[C3B] = color.b
|
vertices[C3B] = color.b
|
||||||
vertices[C3A] = color.a
|
vertices[C3A] = color.a
|
||||||
|
|
||||||
offsetX = offset[OX4]
|
offsetX = offset[OX4]
|
||||||
offsetY = offset[OY4]
|
offsetY = offset[OY4]
|
||||||
vertices[X4] = offsetX * a + offsetY * b + x -- ur
|
vertices[X4] = offsetX * a + offsetY * b + x -- ur
|
||||||
vertices[Y4] = offsetX * c + offsetY * d + y
|
vertices[Y4] = offsetX * c + offsetY * d + y
|
||||||
vertices[C4R] = color.r
|
vertices[C4R] = color.r
|
||||||
vertices[C4G] = color.g
|
vertices[C4G] = color.g
|
||||||
vertices[C4B] = color.b
|
vertices[C4B] = color.b
|
||||||
vertices[C4A] = color.a
|
vertices[C4A] = color.a
|
||||||
|
|
||||||
return vertices
|
return vertices
|
||||||
end
|
end
|
||||||
|
|
||||||
return RegionAttachment
|
return RegionAttachment
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- FIXME the logic in this file uses 0-based indexing. Each array
|
-- FIXME the logic in this file uses 0-based indexing. Each array
|
||||||
-- access adds 1 to the calculated index. We should switch the logic
|
-- access adds 1 to the calculated index. We should switch the logic
|
||||||
-- to 1-based indexing eventually.
|
-- to 1-based indexing eventually.
|
||||||
|
|
||||||
local setmetatable = setmetatable
|
local setmetatable = setmetatable
|
||||||
@ -42,112 +42,112 @@ VertexAttachment.__index = VertexAttachment
|
|||||||
setmetatable(VertexAttachment, { __index = Attachment })
|
setmetatable(VertexAttachment, { __index = Attachment })
|
||||||
|
|
||||||
function VertexAttachment.new (name, attachmentType)
|
function VertexAttachment.new (name, attachmentType)
|
||||||
local self = Attachment.new(name, attachmentType)
|
local self = Attachment.new(name, attachmentType)
|
||||||
self.bones = nil
|
self.bones = nil
|
||||||
self.vertices = nil
|
self.vertices = nil
|
||||||
self.worldVerticesLength = 0
|
self.worldVerticesLength = 0
|
||||||
setmetatable(self, VertexAttachment)
|
setmetatable(self, VertexAttachment)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function VertexAttachment:computeWorldVertices (slot, worldVertices)
|
function VertexAttachment:computeWorldVertices (slot, worldVertices)
|
||||||
self:computeWorldVerticesWith(slot, 0, self.worldVerticesLength, worldVertices, 0)
|
self:computeWorldVerticesWith(slot, 0, self.worldVerticesLength, worldVertices, 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
function VertexAttachment:computeWorldVerticesWith (slot, start, count, worldVertices, offset)
|
function VertexAttachment:computeWorldVerticesWith (slot, start, count, worldVertices, offset)
|
||||||
count = count + offset
|
count = count + offset
|
||||||
local skeleton = slot.bone.skeleton
|
local skeleton = slot.bone.skeleton
|
||||||
local x = skeleton.x
|
local x = skeleton.x
|
||||||
local y = skeleton.y
|
local y = skeleton.y
|
||||||
local deformArray = slot.attachmentVertices
|
local deformArray = slot.attachmentVertices
|
||||||
local vertices = self.vertices
|
local vertices = self.vertices
|
||||||
local bones = self.bones
|
local bones = self.bones
|
||||||
if not bones then
|
if not bones then
|
||||||
if #deformArray > 0 then vertices = deformArray end
|
if #deformArray > 0 then vertices = deformArray end
|
||||||
local bone = slot.bone
|
local bone = slot.bone
|
||||||
x = x + bone.worldX
|
x = x + bone.worldX
|
||||||
y = y + bone.worldY
|
y = y + bone.worldY
|
||||||
local a = bone.a
|
local a = bone.a
|
||||||
local b = bone.b
|
local b = bone.b
|
||||||
local c = bone.c
|
local c = bone.c
|
||||||
local d = bone.d
|
local d = bone.d
|
||||||
local v = start
|
local v = start
|
||||||
local w = offset
|
local w = offset
|
||||||
while w < count do
|
while w < count do
|
||||||
local vx = vertices[v + 1]
|
local vx = vertices[v + 1]
|
||||||
local vy = vertices[v + 2]
|
local vy = vertices[v + 2]
|
||||||
worldVertices[w + 1] = vx * a + vy * b + x
|
worldVertices[w + 1] = vx * a + vy * b + x
|
||||||
worldVertices[w + 2] = vx * c + vy * d + y
|
worldVertices[w + 2] = vx * c + vy * d + y
|
||||||
v = v + 2
|
v = v + 2
|
||||||
w = w + 2
|
w = w + 2
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local v = 0
|
local v = 0
|
||||||
local skip = 0
|
local skip = 0
|
||||||
local i = 0
|
local i = 0
|
||||||
while i < start do
|
while i < start do
|
||||||
local n = bones[v + 1]
|
local n = bones[v + 1]
|
||||||
v = v + n + 1
|
v = v + n + 1
|
||||||
skip = skip + n
|
skip = skip + n
|
||||||
i = i + 2
|
i = i + 2
|
||||||
end
|
end
|
||||||
local skeletonBones = skeleton.bones
|
local skeletonBones = skeleton.bones
|
||||||
if #deformArray == 0 then
|
if #deformArray == 0 then
|
||||||
local w = offset
|
local w = offset
|
||||||
local b = skip * 3
|
local b = skip * 3
|
||||||
while w < count do
|
while w < count do
|
||||||
local wx = x
|
local wx = x
|
||||||
local wy = y
|
local wy = y
|
||||||
local n = bones[v + 1]
|
local n = bones[v + 1]
|
||||||
v = v + 1
|
v = v + 1
|
||||||
n = n + v
|
n = n + v
|
||||||
while v < n do
|
while v < n do
|
||||||
local bone = skeletonBones[bones[v + 1]]
|
local bone = skeletonBones[bones[v + 1]]
|
||||||
local vx = vertices[b + 1]
|
local vx = vertices[b + 1]
|
||||||
local vy = vertices[b + 2]
|
local vy = vertices[b + 2]
|
||||||
local weight = vertices[b + 3]
|
local weight = vertices[b + 3]
|
||||||
wx = wx + (vx * bone.a + vy * bone.b + bone.worldX) * weight
|
wx = wx + (vx * bone.a + vy * bone.b + bone.worldX) * weight
|
||||||
wy = wy + (vx * bone.c + vy * bone.d + bone.worldY) * weight
|
wy = wy + (vx * bone.c + vy * bone.d + bone.worldY) * weight
|
||||||
v = v + 1
|
v = v + 1
|
||||||
b = b + 3
|
b = b + 3
|
||||||
end
|
end
|
||||||
worldVertices[w + 1] = wx
|
worldVertices[w + 1] = wx
|
||||||
worldVertices[w + 2] = wy
|
worldVertices[w + 2] = wy
|
||||||
w = w + 2
|
w = w + 2
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local deform = deformArray
|
local deform = deformArray
|
||||||
local w = offset
|
local w = offset
|
||||||
local b = skip * 3
|
local b = skip * 3
|
||||||
local f = skip * 2
|
local f = skip * 2
|
||||||
while w < count do
|
while w < count do
|
||||||
local wx = x
|
local wx = x
|
||||||
local wy = y
|
local wy = y
|
||||||
local n = bones[v + 1]
|
local n = bones[v + 1]
|
||||||
v = v + 1
|
v = v + 1
|
||||||
n = n + v
|
n = n + v
|
||||||
|
|
||||||
while v < n do
|
while v < n do
|
||||||
local bone = skeletonBones[bones[v + 1]]
|
local bone = skeletonBones[bones[v + 1]]
|
||||||
local vx = vertices[b + 1] + deform[f + 1]
|
local vx = vertices[b + 1] + deform[f + 1]
|
||||||
local vy = vertices[b + 2] + deform[f + 2]
|
local vy = vertices[b + 2] + deform[f + 2]
|
||||||
local weight = vertices[b + 3]
|
local weight = vertices[b + 3]
|
||||||
wx = wx + (vx * bone.a + vy * bone.b + bone.worldX) * weight
|
wx = wx + (vx * bone.a + vy * bone.b + bone.worldX) * weight
|
||||||
wy = wy + (vx * bone.c + vy * bone.d + bone.worldY) * weight
|
wy = wy + (vx * bone.c + vy * bone.d + bone.worldY) * weight
|
||||||
v = v + 1
|
v = v + 1
|
||||||
b = b + 3
|
b = b + 3
|
||||||
f = f + 2
|
f = f + 2
|
||||||
end
|
end
|
||||||
worldVertices[w + 1] = wx
|
worldVertices[w + 1] = wx
|
||||||
worldVertices[w + 2] = wy
|
worldVertices[w + 2] = wy
|
||||||
w = w + 2
|
w = w + 2
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function VertexAttachment:applyDeform (sourceAttachment)
|
function VertexAttachment:applyDeform (sourceAttachment)
|
||||||
return self == sourceAttachment
|
return self == sourceAttachment
|
||||||
end
|
end
|
||||||
|
|
||||||
return VertexAttachment
|
return VertexAttachment
|
||||||
|
|||||||
@ -80,8 +80,8 @@ end
|
|||||||
function utils.newNumberArray (size)
|
function utils.newNumberArray (size)
|
||||||
local a = {}
|
local a = {}
|
||||||
local i = 1
|
local i = 1
|
||||||
while i <= size do
|
while i <= size do
|
||||||
a[i] = 0
|
a[i] = 0
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
return a
|
return a
|
||||||
@ -90,8 +90,8 @@ end
|
|||||||
function utils.newNumberArrayZero (size)
|
function utils.newNumberArrayZero (size)
|
||||||
local a = {}
|
local a = {}
|
||||||
local i = 0
|
local i = 0
|
||||||
while i < size do
|
while i < size do
|
||||||
a[i] = 0
|
a[i] = 0
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
return a
|
return a
|
||||||
@ -101,7 +101,7 @@ function utils.setArraySize (array, size)
|
|||||||
if #array == size then return array end
|
if #array == size then return array end
|
||||||
if #array < size then
|
if #array < size then
|
||||||
local i = #array + 1
|
local i = #array + 1
|
||||||
while i <= size do
|
while i <= size do
|
||||||
array[i] = 0
|
array[i] = 0
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
|
|||||||
@ -62,9 +62,9 @@ char* _Util_readFile (const char* path, int* length){
|
|||||||
namespace spine {
|
namespace spine {
|
||||||
|
|
||||||
SkeletonDrawable::SkeletonDrawable (SkeletonData* skeletonData, AnimationStateData* stateData) :
|
SkeletonDrawable::SkeletonDrawable (SkeletonData* skeletonData, AnimationStateData* stateData) :
|
||||||
timeScale(1),
|
timeScale(1),
|
||||||
vertexArray(new VertexArray(Triangles, skeletonData->bonesCount * 4)),
|
vertexArray(new VertexArray(Triangles, skeletonData->bonesCount * 4)),
|
||||||
worldVertices(0) {
|
worldVertices(0) {
|
||||||
Bone_setYDown(true);
|
Bone_setYDown(true);
|
||||||
worldVertices = MALLOC(float, SPINE_MESH_VERTEX_COUNT_MAX);
|
worldVertices = MALLOC(float, SPINE_MESH_VERTEX_COUNT_MAX);
|
||||||
skeleton = Skeleton_create(skeletonData);
|
skeleton = Skeleton_create(skeletonData);
|
||||||
@ -78,7 +78,7 @@ SkeletonDrawable::SkeletonDrawable (SkeletonData* skeletonData, AnimationStateDa
|
|||||||
SkeletonDrawable::~SkeletonDrawable () {
|
SkeletonDrawable::~SkeletonDrawable () {
|
||||||
delete vertexArray;
|
delete vertexArray;
|
||||||
FREE(worldVertices);
|
FREE(worldVertices);
|
||||||
if (ownsAnimationStateData) AnimationStateData_dispose(state->data);
|
if (ownsAnimationStateData) AnimationStateData_dispose(state->data);
|
||||||
AnimationState_dispose(state);
|
AnimationState_dispose(state);
|
||||||
Skeleton_dispose(skeleton);
|
Skeleton_dispose(skeleton);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,7 +38,7 @@ import starling.animation.IAnimatable;
|
|||||||
public class SkeletonAnimation extends SkeletonSprite implements IAnimatable {
|
public class SkeletonAnimation extends SkeletonSprite implements IAnimatable {
|
||||||
public var state:AnimationState;
|
public var state:AnimationState;
|
||||||
public var timeScale:Number = 1;
|
public var timeScale:Number = 1;
|
||||||
|
|
||||||
public function SkeletonAnimation (skeletonData:SkeletonData, stateData:AnimationStateData = null) {
|
public function SkeletonAnimation (skeletonData:SkeletonData, stateData:AnimationStateData = null) {
|
||||||
super(skeletonData);
|
super(skeletonData);
|
||||||
state = new AnimationState(stateData ? stateData : new AnimationStateData(skeletonData));
|
state = new AnimationState(stateData ? stateData : new AnimationStateData(skeletonData));
|
||||||
|
|||||||
@ -36,16 +36,16 @@ import starling.rendering.VertexData;
|
|||||||
import starling.display.Mesh;
|
import starling.display.Mesh;
|
||||||
|
|
||||||
public class SkeletonMesh extends Mesh {
|
public class SkeletonMesh extends Mesh {
|
||||||
|
|
||||||
public function SkeletonMesh(texture:Texture, vertexData:VertexData = null, indexData:IndexData = null, style:MeshStyle=null) {
|
public function SkeletonMesh(texture:Texture, vertexData:VertexData = null, indexData:IndexData = null, style:MeshStyle=null) {
|
||||||
super(vertexData == null? new VertexData(): vertexData, indexData == null? new IndexData(): indexData, style);
|
super(vertexData == null? new VertexData(): vertexData, indexData == null? new IndexData(): indexData, style);
|
||||||
this.texture = texture;
|
this.texture = texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getVertexData(): VertexData {
|
public function getVertexData(): VertexData {
|
||||||
return this.vertexData;
|
return this.vertexData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getIndexData(): IndexData {
|
public function getIndexData(): IndexData {
|
||||||
return this.indexData;
|
return this.indexData;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,14 +54,14 @@ import flash.geom.Rectangle;
|
|||||||
public class SkeletonSprite extends DisplayObject {
|
public class SkeletonSprite extends DisplayObject {
|
||||||
static private var _tempPoint:Point = new Point();
|
static private var _tempPoint:Point = new Point();
|
||||||
static private var _tempMatrix:Matrix = new Matrix();
|
static private var _tempMatrix:Matrix = new Matrix();
|
||||||
static private var _tempVertices:Vector.<Number> = new Vector.<Number>(8);
|
static private var _tempVertices:Vector.<Number> = new Vector.<Number>(8);
|
||||||
static internal var blendModes:Vector.<String> = new <String>[
|
static internal var blendModes:Vector.<String> = new <String>[
|
||||||
BlendMode.NORMAL, BlendMode.ADD, BlendMode.MULTIPLY, BlendMode.SCREEN];
|
BlendMode.NORMAL, BlendMode.ADD, BlendMode.MULTIPLY, BlendMode.SCREEN];
|
||||||
|
|
||||||
private var _skeleton:Skeleton;
|
private var _skeleton:Skeleton;
|
||||||
public var batchable:Boolean = true;
|
public var batchable:Boolean = true;
|
||||||
private var _smoothing:String = "bilinear";
|
private var _smoothing:String = "bilinear";
|
||||||
|
|
||||||
public function SkeletonSprite (skeletonData:SkeletonData) {
|
public function SkeletonSprite (skeletonData:SkeletonData) {
|
||||||
Bone.yDown = true;
|
Bone.yDown = true;
|
||||||
_skeleton = new Skeleton(skeletonData);
|
_skeleton = new Skeleton(skeletonData);
|
||||||
@ -69,7 +69,7 @@ public class SkeletonSprite extends DisplayObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override public function render (painter:Painter) : void {
|
override public function render (painter:Painter) : void {
|
||||||
alpha *= this.alpha * skeleton.a;
|
alpha *= this.alpha * skeleton.a;
|
||||||
var originalBlendMode:String = painter.state.blendMode;
|
var originalBlendMode:String = painter.state.blendMode;
|
||||||
var r:Number = skeleton.r * 255;
|
var r:Number = skeleton.r * 255;
|
||||||
var g:Number = skeleton.g * 255;
|
var g:Number = skeleton.g * 255;
|
||||||
@ -81,12 +81,12 @@ public class SkeletonSprite extends DisplayObject {
|
|||||||
var ii:int, iii:int;
|
var ii:int, iii:int;
|
||||||
var rgb:uint, a:Number;
|
var rgb:uint, a:Number;
|
||||||
var mesh:SkeletonMesh;
|
var mesh:SkeletonMesh;
|
||||||
var verticesLength:int, verticesCount:int, indicesLength:int;
|
var verticesLength:int, verticesCount:int, indicesLength:int;
|
||||||
var indexData:IndexData, indices:Vector.<uint>, vertexData:VertexData;
|
var indexData:IndexData, indices:Vector.<uint>, vertexData:VertexData;
|
||||||
var uvs: Vector.<Number>;
|
var uvs: Vector.<Number>;
|
||||||
|
|
||||||
for (var i:int = 0, n:int = drawOrder.length; i < n; ++i) {
|
for (var i:int = 0, n:int = drawOrder.length; i < n; ++i) {
|
||||||
var slot:Slot = drawOrder[i];
|
var slot:Slot = drawOrder[i];
|
||||||
if (slot.attachment is RegionAttachment) {
|
if (slot.attachment is RegionAttachment) {
|
||||||
var region:RegionAttachment = slot.attachment as RegionAttachment;
|
var region:RegionAttachment = slot.attachment as RegionAttachment;
|
||||||
region.computeWorldVertices(x, y, slot.bone, worldVertices);
|
region.computeWorldVertices(x, y, slot.bone, worldVertices);
|
||||||
@ -106,41 +106,41 @@ public class SkeletonSprite extends DisplayObject {
|
|||||||
image.setTexCoords(j, p.x, p.y);
|
image.setTexCoords(j, p.x, p.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
image.setVertexPosition(0, worldVertices[2], worldVertices[3]);
|
image.setVertexPosition(0, worldVertices[2], worldVertices[3]);
|
||||||
image.setVertexColor(0, rgb);
|
image.setVertexColor(0, rgb);
|
||||||
image.setVertexAlpha(0, a);
|
image.setVertexAlpha(0, a);
|
||||||
|
|
||||||
image.setVertexPosition(1, worldVertices[4], worldVertices[5]);
|
image.setVertexPosition(1, worldVertices[4], worldVertices[5]);
|
||||||
image.setVertexColor(1, rgb);
|
image.setVertexColor(1, rgb);
|
||||||
image.setVertexAlpha(1, a);
|
image.setVertexAlpha(1, a);
|
||||||
|
|
||||||
image.setVertexPosition(2, worldVertices[0], worldVertices[1]);
|
image.setVertexPosition(2, worldVertices[0], worldVertices[1]);
|
||||||
image.setVertexColor(2, rgb);
|
image.setVertexColor(2, rgb);
|
||||||
image.setVertexAlpha(2, a);
|
image.setVertexAlpha(2, a);
|
||||||
|
|
||||||
image.setVertexPosition(3, worldVertices[6], worldVertices[7]);
|
image.setVertexPosition(3, worldVertices[6], worldVertices[7]);
|
||||||
image.setVertexColor(3, rgb);
|
image.setVertexColor(3, rgb);
|
||||||
image.setVertexAlpha(3, a);
|
image.setVertexAlpha(3, a);
|
||||||
|
|
||||||
image.setRequiresRedraw();
|
image.setRequiresRedraw();
|
||||||
painter.state.blendMode = blendModes[slot.data.blendMode.ordinal];
|
painter.state.blendMode = blendModes[slot.data.blendMode.ordinal];
|
||||||
// FIXME set smoothing/filter
|
// FIXME set smoothing/filter
|
||||||
painter.batchMesh(image);
|
painter.batchMesh(image);
|
||||||
} else if (slot.attachment is MeshAttachment) {
|
} else if (slot.attachment is MeshAttachment) {
|
||||||
var meshAttachment:MeshAttachment = MeshAttachment(slot.attachment);
|
var meshAttachment:MeshAttachment = MeshAttachment(slot.attachment);
|
||||||
verticesLength = meshAttachment.worldVerticesLength;
|
verticesLength = meshAttachment.worldVerticesLength;
|
||||||
verticesCount = verticesLength >> 1;
|
verticesCount = verticesLength >> 1;
|
||||||
if (worldVertices.length < verticesLength) worldVertices.length = verticesLength;
|
if (worldVertices.length < verticesLength) worldVertices.length = verticesLength;
|
||||||
meshAttachment.computeWorldVertices(slot, worldVertices);
|
meshAttachment.computeWorldVertices(slot, worldVertices);
|
||||||
mesh = meshAttachment.rendererObject as SkeletonMesh;
|
mesh = meshAttachment.rendererObject as SkeletonMesh;
|
||||||
if (mesh == null) {
|
if (mesh == null) {
|
||||||
if (meshAttachment.rendererObject is Image)
|
if (meshAttachment.rendererObject is Image)
|
||||||
meshAttachment.rendererObject = mesh = new SkeletonMesh(Image(meshAttachment.rendererObject).texture);
|
meshAttachment.rendererObject = mesh = new SkeletonMesh(Image(meshAttachment.rendererObject).texture);
|
||||||
if (meshAttachment.rendererObject is AtlasRegion)
|
if (meshAttachment.rendererObject is AtlasRegion)
|
||||||
meshAttachment.rendererObject = mesh = new SkeletonMesh(Image(AtlasRegion(meshAttachment.rendererObject).rendererObject).texture);
|
meshAttachment.rendererObject = mesh = new SkeletonMesh(Image(AtlasRegion(meshAttachment.rendererObject).rendererObject).texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh.numIndices != meshAttachment.triangles.length) {
|
if (mesh.numIndices != meshAttachment.triangles.length) {
|
||||||
indexData = mesh.getIndexData();
|
indexData = mesh.getIndexData();
|
||||||
indices = meshAttachment.triangles;
|
indices = meshAttachment.triangles;
|
||||||
@ -151,24 +151,24 @@ public class SkeletonSprite extends DisplayObject {
|
|||||||
indexData.numIndices = indicesLength;
|
indexData.numIndices = indicesLength;
|
||||||
indexData.trim();
|
indexData.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME pre-multiplied alpha?
|
// FIXME pre-multiplied alpha?
|
||||||
a = slot.a * meshAttachment.a;
|
a = slot.a * meshAttachment.a;
|
||||||
rgb = Color.rgb(
|
rgb = Color.rgb(
|
||||||
r * slot.r * meshAttachment.r,
|
r * slot.r * meshAttachment.r,
|
||||||
g * slot.g * meshAttachment.g,
|
g * slot.g * meshAttachment.g,
|
||||||
b * slot.b * meshAttachment.b);
|
b * slot.b * meshAttachment.b);
|
||||||
|
|
||||||
vertexData = mesh.getVertexData();
|
vertexData = mesh.getVertexData();
|
||||||
uvs = meshAttachment.uvs;
|
uvs = meshAttachment.uvs;
|
||||||
vertexData.colorize("color", rgb, a);
|
vertexData.colorize("color", rgb, a);
|
||||||
for (ii = 0, iii = 0; ii < verticesCount; ii++, iii+=2) {
|
for (ii = 0, iii = 0; ii < verticesCount; ii++, iii+=2) {
|
||||||
mesh.setVertexPosition(ii, worldVertices[iii], worldVertices[iii+1]);
|
mesh.setVertexPosition(ii, worldVertices[iii], worldVertices[iii+1]);
|
||||||
mesh.setTexCoords(ii, uvs[iii], uvs[iii+1]);
|
mesh.setTexCoords(ii, uvs[iii], uvs[iii+1]);
|
||||||
}
|
}
|
||||||
vertexData.numVertices = verticesCount;
|
vertexData.numVertices = verticesCount;
|
||||||
// FIXME set smoothing/filter
|
// FIXME set smoothing/filter
|
||||||
painter.batchMesh(mesh);
|
painter.batchMesh(mesh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
painter.state.blendMode = originalBlendMode;
|
painter.state.blendMode = originalBlendMode;
|
||||||
@ -196,7 +196,7 @@ public class SkeletonSprite extends DisplayObject {
|
|||||||
var mesh:MeshAttachment = MeshAttachment(attachment);
|
var mesh:MeshAttachment = MeshAttachment(attachment);
|
||||||
verticesLength = mesh.worldVerticesLength;
|
verticesLength = mesh.worldVerticesLength;
|
||||||
if (worldVertices.length < verticesLength) worldVertices.length = verticesLength;
|
if (worldVertices.length < verticesLength) worldVertices.length = verticesLength;
|
||||||
mesh.computeWorldVertices(slot, worldVertices);
|
mesh.computeWorldVertices(slot, worldVertices);
|
||||||
} else
|
} else
|
||||||
continue;
|
continue;
|
||||||
for (var ii:int = 0; ii < verticesLength; ii += 2) {
|
for (var ii:int = 0; ii < verticesLength; ii += 2) {
|
||||||
@ -240,7 +240,7 @@ public class SkeletonSprite extends DisplayObject {
|
|||||||
}
|
}
|
||||||
return resultRect;
|
return resultRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get skeleton () : Skeleton {
|
public function get skeleton () : Skeleton {
|
||||||
return _skeleton;
|
return _skeleton;
|
||||||
}
|
}
|
||||||
@ -250,7 +250,7 @@ public class SkeletonSprite extends DisplayObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function set smoothing (smoothing:String) : void {
|
public function set smoothing (smoothing:String) : void {
|
||||||
_smoothing = smoothing;
|
_smoothing = smoothing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -99,7 +99,7 @@ public class StarlingAtlasAttachmentLoader implements AttachmentLoader {
|
|||||||
attachment.regionV = rectRegion.y / root.height;
|
attachment.regionV = rectRegion.y / root.height;
|
||||||
attachment.regionU2 = (rectRegion.x + subTexture.width) / root.width;
|
attachment.regionU2 = (rectRegion.x + subTexture.width) / root.width;
|
||||||
attachment.regionV2 = (rectRegion.y + subTexture.height) / root.height;
|
attachment.regionV2 = (rectRegion.y + subTexture.height) / root.height;
|
||||||
attachment.rendererObject = new Image(root);
|
attachment.rendererObject = new Image(root);
|
||||||
} else {
|
} else {
|
||||||
attachment.regionU = 0;
|
attachment.regionU = 0;
|
||||||
attachment.regionV = 1;
|
attachment.regionV = 1;
|
||||||
@ -119,7 +119,7 @@ public class StarlingAtlasAttachmentLoader implements AttachmentLoader {
|
|||||||
public function newBoundingBoxAttachment (skin:Skin, name:String) : BoundingBoxAttachment {
|
public function newBoundingBoxAttachment (skin:Skin, name:String) : BoundingBoxAttachment {
|
||||||
return new BoundingBoxAttachment(name);
|
return new BoundingBoxAttachment(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function newPathAttachment (skin:Skin, name:String) : PathAttachment {
|
public function newPathAttachment (skin:Skin, name:String) : PathAttachment {
|
||||||
return new PathAttachment(name);
|
return new PathAttachment(name);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,7 +43,7 @@ public class StarlingTextureLoader implements TextureLoader {
|
|||||||
public var bitmapDatas:Object = {};
|
public var bitmapDatas:Object = {};
|
||||||
public var singleBitmapData:BitmapData;
|
public var singleBitmapData:BitmapData;
|
||||||
|
|
||||||
/** @param bitmaps A Bitmap or BitmapData for an atlas that has only one page, or for a multi page atlas an object where the
|
/** @param bitmaps A Bitmap or BitmapData for an atlas that has only one page, or for a multi page atlas an object where the
|
||||||
* key is the image path and the value is the Bitmap or BitmapData. */
|
* key is the image path and the value is the Bitmap or BitmapData. */
|
||||||
public function StarlingTextureLoader (bitmaps:Object) {
|
public function StarlingTextureLoader (bitmaps:Object) {
|
||||||
if (bitmaps is BitmapData) {
|
if (bitmaps is BitmapData) {
|
||||||
@ -54,7 +54,7 @@ public class StarlingTextureLoader implements TextureLoader {
|
|||||||
singleBitmapData = Bitmap(bitmaps).bitmapData;
|
singleBitmapData = Bitmap(bitmaps).bitmapData;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var path:* in bitmaps) {
|
for (var path:* in bitmaps) {
|
||||||
var object:* = bitmaps[path];
|
var object:* = bitmaps[path];
|
||||||
var bitmapData:BitmapData;
|
var bitmapData:BitmapData;
|
||||||
@ -79,7 +79,7 @@ public class StarlingTextureLoader implements TextureLoader {
|
|||||||
|
|
||||||
public function loadRegion (region:AtlasRegion) : void {
|
public function loadRegion (region:AtlasRegion) : void {
|
||||||
var image:Image = new Image(Texture(region.page.rendererObject));
|
var image:Image = new Image(Texture(region.page.rendererObject));
|
||||||
if (region.rotate) {
|
if (region.rotate) {
|
||||||
image.setTexCoords(0, region.u, region.v2);
|
image.setTexCoords(0, region.u, region.v2);
|
||||||
image.setTexCoords(1, region.u, region.v);
|
image.setTexCoords(1, region.u, region.v);
|
||||||
image.setTexCoords(2, region.u2, region.v2);
|
image.setTexCoords(2, region.u2, region.v2);
|
||||||
|
|||||||
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
/// <reference path="../../core/src/Texture.ts"/>
|
/// <reference path="../../core/src/Texture.ts"/>
|
||||||
|
|
||||||
module spine.canvas {
|
module spine.canvas {
|
||||||
export class CanvasTexture extends Texture {
|
export class CanvasTexture extends Texture {
|
||||||
constructor (image: HTMLImageElement) {
|
constructor (image: HTMLImageElement) {
|
||||||
super(image);
|
super(image);
|
||||||
|
|||||||
@ -31,12 +31,12 @@
|
|||||||
module spine.canvas {
|
module spine.canvas {
|
||||||
export class SkeletonRenderer {
|
export class SkeletonRenderer {
|
||||||
static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
|
static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
|
||||||
|
|
||||||
private ctx: CanvasRenderingContext2D;
|
private ctx: CanvasRenderingContext2D;
|
||||||
|
|
||||||
public triangleRendering = false;
|
public triangleRendering = false;
|
||||||
public debugRendering = false;
|
public debugRendering = false;
|
||||||
|
|
||||||
constructor (context: CanvasRenderingContext2D) {
|
constructor (context: CanvasRenderingContext2D) {
|
||||||
this.ctx = context;
|
this.ctx = context;
|
||||||
}
|
}
|
||||||
@ -50,21 +50,21 @@ module spine.canvas {
|
|||||||
let ctx = this.ctx;
|
let ctx = this.ctx;
|
||||||
let drawOrder = skeleton.drawOrder;
|
let drawOrder = skeleton.drawOrder;
|
||||||
|
|
||||||
if (this.debugRendering) ctx.strokeStyle = "green";
|
if (this.debugRendering) ctx.strokeStyle = "green";
|
||||||
|
|
||||||
for (let i = 0, n = drawOrder.length; i < n; i++) {
|
for (let i = 0, n = drawOrder.length; i < n; i++) {
|
||||||
let slot = drawOrder[i];
|
let slot = drawOrder[i];
|
||||||
let attachment = slot.getAttachment();
|
let attachment = slot.getAttachment();
|
||||||
let region: TextureAtlasRegion = null;
|
let region: TextureAtlasRegion = null;
|
||||||
let image: HTMLImageElement = null;
|
let image: HTMLImageElement = null;
|
||||||
let vertices: ArrayLike<number> = null;
|
let vertices: ArrayLike<number> = null;
|
||||||
if (attachment instanceof RegionAttachment) {
|
if (attachment instanceof RegionAttachment) {
|
||||||
let regionAttachment = <RegionAttachment>attachment;
|
let regionAttachment = <RegionAttachment>attachment;
|
||||||
vertices = regionAttachment.updateWorldVertices(slot, false);
|
vertices = regionAttachment.updateWorldVertices(slot, false);
|
||||||
region = <TextureAtlasRegion>regionAttachment.region;
|
region = <TextureAtlasRegion>regionAttachment.region;
|
||||||
image = (<CanvasTexture>(region).texture).getImage();
|
image = (<CanvasTexture>(region).texture).getImage();
|
||||||
|
|
||||||
} else continue;
|
} else continue;
|
||||||
|
|
||||||
let att = <RegionAttachment>attachment;
|
let att = <RegionAttachment>attachment;
|
||||||
let bone = slot.bone;
|
let bone = slot.bone;
|
||||||
@ -75,28 +75,28 @@ module spine.canvas {
|
|||||||
let xy = vertices[25] - vertices[1];
|
let xy = vertices[25] - vertices[1];
|
||||||
let yx = vertices[8] - vertices[0];
|
let yx = vertices[8] - vertices[0];
|
||||||
let yy = vertices[9] - vertices[1];
|
let yy = vertices[9] - vertices[1];
|
||||||
let w = Math.sqrt(xx * xx + xy * xy), h = -Math.sqrt(yx * yx + yy * yy);
|
let w = Math.sqrt(xx * xx + xy * xy), h = -Math.sqrt(yx * yx + yy * yy);
|
||||||
ctx.translate(x, y);
|
ctx.translate(x, y);
|
||||||
ctx.rotate(rotation);
|
ctx.rotate(rotation);
|
||||||
if (region.rotate) {
|
if (region.rotate) {
|
||||||
ctx.rotate(Math.PI / 2);
|
ctx.rotate(Math.PI / 2);
|
||||||
ctx.drawImage(image, region.x, region.y, region.height, region.width, 0, 0, h, -w);
|
ctx.drawImage(image, region.x, region.y, region.height, region.width, 0, 0, h, -w);
|
||||||
ctx.rotate(-Math.PI / 2);
|
ctx.rotate(-Math.PI / 2);
|
||||||
} else {
|
} else {
|
||||||
ctx.drawImage(image, region.x, region.y, region.width, region.height, 0, 0, w, h);
|
ctx.drawImage(image, region.x, region.y, region.width, region.height, 0, 0, w, h);
|
||||||
}
|
}
|
||||||
if (this.debugRendering) ctx.strokeRect(0, 0, w, h);
|
if (this.debugRendering) ctx.strokeRect(0, 0, w, h);
|
||||||
ctx.rotate(-rotation);
|
ctx.rotate(-rotation);
|
||||||
ctx.translate(-x, -y);
|
ctx.translate(-x, -y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private drawTriangles (skeleton: Skeleton) {
|
private drawTriangles (skeleton: Skeleton) {
|
||||||
let blendMode: BlendMode = null;
|
let blendMode: BlendMode = null;
|
||||||
|
|
||||||
let vertices: ArrayLike<number> = null;
|
let vertices: ArrayLike<number> = null;
|
||||||
let triangles: Array<number> = null;
|
let triangles: Array<number> = null;
|
||||||
let drawOrder = skeleton.drawOrder;
|
let drawOrder = skeleton.drawOrder;
|
||||||
|
|
||||||
for (let i = 0, n = drawOrder.length; i < n; i++) {
|
for (let i = 0, n = drawOrder.length; i < n; i++) {
|
||||||
let slot = drawOrder[i];
|
let slot = drawOrder[i];
|
||||||
@ -115,22 +115,22 @@ module spine.canvas {
|
|||||||
vertices = mesh.updateWorldVertices(slot, false);
|
vertices = mesh.updateWorldVertices(slot, false);
|
||||||
triangles = mesh.triangles;
|
triangles = mesh.triangles;
|
||||||
texture = (<TextureAtlasRegion>mesh.region.renderObject).texture.getImage();
|
texture = (<TextureAtlasRegion>mesh.region.renderObject).texture.getImage();
|
||||||
} else continue;
|
} else continue;
|
||||||
|
|
||||||
if (texture != null) {
|
if (texture != null) {
|
||||||
let slotBlendMode = slot.data.blendMode;
|
let slotBlendMode = slot.data.blendMode;
|
||||||
if (slotBlendMode != blendMode) {
|
if (slotBlendMode != blendMode) {
|
||||||
blendMode = slotBlendMode;
|
blendMode = slotBlendMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ctx = this.ctx;
|
let ctx = this.ctx;
|
||||||
|
|
||||||
for (var j = 0; j < triangles.length; j+=3) {
|
for (var j = 0; j < triangles.length; j+=3) {
|
||||||
let t1 = triangles[j] * 8, t2 = triangles[j+1] * 8, t3 = triangles[j+2] * 8;
|
let t1 = triangles[j] * 8, t2 = triangles[j+1] * 8, t3 = triangles[j+2] * 8;
|
||||||
|
|
||||||
let x0 = vertices[t1], y0 = vertices[t1 + 1], u0 = vertices[t1 + 6], v0 = vertices[t1 + 7];
|
let x0 = vertices[t1], y0 = vertices[t1 + 1], u0 = vertices[t1 + 6], v0 = vertices[t1 + 7];
|
||||||
let x1 = vertices[t2], y1 = vertices[t2 + 1], u1 = vertices[t2 + 6], v1 = vertices[t2 + 7];
|
let x1 = vertices[t2], y1 = vertices[t2 + 1], u1 = vertices[t2 + 6], v1 = vertices[t2 + 7];
|
||||||
let x2 = vertices[t3], y2 = vertices[t3 + 1], u2 = vertices[t3 + 6], v2 = vertices[t3 + 7];
|
let x2 = vertices[t3], y2 = vertices[t3 + 1], u2 = vertices[t3 + 6], v2 = vertices[t3 + 7];
|
||||||
|
|
||||||
this.drawTriangle(texture, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2);
|
this.drawTriangle(texture, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2);
|
||||||
|
|
||||||
@ -140,13 +140,13 @@ module spine.canvas {
|
|||||||
ctx.moveTo(x0, y0);
|
ctx.moveTo(x0, y0);
|
||||||
ctx.lineTo(x1, y1);
|
ctx.lineTo(x1, y1);
|
||||||
ctx.lineTo(x2, y2);
|
ctx.lineTo(x2, y2);
|
||||||
ctx.lineTo(x0, y0);
|
ctx.lineTo(x0, y0);
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adapted from http://extremelysatisfactorytotalitarianism.com/blog/?p=2120
|
// Adapted from http://extremelysatisfactorytotalitarianism.com/blog/?p=2120
|
||||||
// Apache 2 licensed
|
// Apache 2 licensed
|
||||||
@ -194,7 +194,7 @@ module spine.canvas {
|
|||||||
ctx.transform(a, b, c, d, e, f);
|
ctx.transform(a, b, c, d, e, f);
|
||||||
ctx.clip();
|
ctx.clip();
|
||||||
ctx.drawImage(img, 0, 0);
|
ctx.drawImage(img, 0, 0);
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -102,7 +102,7 @@ module spine {
|
|||||||
|
|
||||||
constructor (frameCount: number) {
|
constructor (frameCount: number) {
|
||||||
if (frameCount <= 0) throw new Error("frameCount must be > 0: " + frameCount);
|
if (frameCount <= 0) throw new Error("frameCount must be > 0: " + frameCount);
|
||||||
this.curves = Utils.newFloatArray((frameCount - 1) * CurveTimeline.BEZIER_SIZE);
|
this.curves = Utils.newFloatArray((frameCount - 1) * CurveTimeline.BEZIER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
getFrameCount () {
|
getFrameCount () {
|
||||||
|
|||||||
@ -136,7 +136,7 @@ module spine {
|
|||||||
if (current == null) return;
|
if (current == null) return;
|
||||||
|
|
||||||
if (current.listener != null && current.listener.end != null) current.listener.end(trackIndex);
|
if (current.listener != null && current.listener.end != null) current.listener.end(trackIndex);
|
||||||
for (let i = 0, n = this.listeners.length; i < n; i++)
|
for (let i = 0, n = this.listeners.length; i < n; i++)
|
||||||
if (this.listeners[i].end) this.listeners[i].end(trackIndex);
|
if (this.listeners[i].end) this.listeners[i].end(trackIndex);
|
||||||
|
|
||||||
this.tracks[trackIndex] = null;
|
this.tracks[trackIndex] = null;
|
||||||
|
|||||||
@ -84,7 +84,7 @@ module spine {
|
|||||||
}
|
}
|
||||||
img.onerror = (ev) => {
|
img.onerror = (ev) => {
|
||||||
if (error) error(path, `Couldn't load image ${path}`);
|
if (error) error(path, `Couldn't load image ${path}`);
|
||||||
this.errors[path] = `Couldn't load image ${path}`;
|
this.errors[path] = `Couldn't load image ${path}`;
|
||||||
this.toLoad--;
|
this.toLoad--;
|
||||||
this.loaded++;
|
this.loaded++;
|
||||||
}
|
}
|
||||||
@ -98,7 +98,7 @@ module spine {
|
|||||||
remove (path: string) {
|
remove (path: string) {
|
||||||
path = this.pathPrefix + path;
|
path = this.pathPrefix + path;
|
||||||
let asset = this.assets[path];
|
let asset = this.assets[path];
|
||||||
if ((<any>asset).dispose) (<any>asset).dispose();
|
if ((<any>asset).dispose) (<any>asset).dispose();
|
||||||
this.assets[path] = null;
|
this.assets[path] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -42,7 +42,7 @@ module spine {
|
|||||||
if (region == null) throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")");
|
if (region == null) throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")");
|
||||||
region.renderObject = region;
|
region.renderObject = region;
|
||||||
let attachment = new RegionAttachment(name);
|
let attachment = new RegionAttachment(name);
|
||||||
attachment.setRegion(region);
|
attachment.setRegion(region);
|
||||||
return attachment;
|
return attachment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,7 @@ module spine {
|
|||||||
clientId: string;
|
clientId: string;
|
||||||
toLoad = new Array<string>();
|
toLoad = new Array<string>();
|
||||||
assets: Map<any> = {};
|
assets: Map<any> = {};
|
||||||
textureLoader: (image: HTMLImageElement) => any;
|
textureLoader: (image: HTMLImageElement) => any;
|
||||||
|
|
||||||
constructor(clientId: string) {
|
constructor(clientId: string) {
|
||||||
this.clientId = clientId;
|
this.clientId = clientId;
|
||||||
@ -47,13 +47,13 @@ module spine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class SharedAssetManager implements Disposable {
|
export class SharedAssetManager implements Disposable {
|
||||||
private pathPrefix: string;
|
private pathPrefix: string;
|
||||||
private clientAssets: Map<Assets> = {};
|
private clientAssets: Map<Assets> = {};
|
||||||
private queuedAssets: Map<string> = {};
|
private queuedAssets: Map<string> = {};
|
||||||
private rawAssets: Map<any> = {}
|
private rawAssets: Map<any> = {}
|
||||||
private errors: Map<string> = {};
|
private errors: Map<string> = {};
|
||||||
|
|
||||||
constructor (pathPrefix: string = "") {
|
constructor (pathPrefix: string = "") {
|
||||||
this.pathPrefix = pathPrefix;
|
this.pathPrefix = pathPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,13 +78,13 @@ module spine {
|
|||||||
|
|
||||||
loadText(clientId: string, path: string) {
|
loadText(clientId: string, path: string) {
|
||||||
path = this.pathPrefix + path;
|
path = this.pathPrefix + path;
|
||||||
if (!this.queueAsset(clientId, null, path)) return;
|
if (!this.queueAsset(clientId, null, path)) return;
|
||||||
let request = new XMLHttpRequest();
|
let request = new XMLHttpRequest();
|
||||||
request.onreadystatechange = () => {
|
request.onreadystatechange = () => {
|
||||||
if (request.readyState == XMLHttpRequest.DONE) {
|
if (request.readyState == XMLHttpRequest.DONE) {
|
||||||
if (request.status >= 200 && request.status < 300) {
|
if (request.status >= 200 && request.status < 300) {
|
||||||
this.rawAssets[path] = request.responseText;
|
this.rawAssets[path] = request.responseText;
|
||||||
} else {
|
} else {
|
||||||
this.errors[path] = `Couldn't load text ${path}: status ${request.status}, ${request.responseText}`;
|
this.errors[path] = `Couldn't load text ${path}: status ${request.status}, ${request.responseText}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,13 +95,13 @@ module spine {
|
|||||||
|
|
||||||
loadJson(clientId: string, path: string) {
|
loadJson(clientId: string, path: string) {
|
||||||
path = this.pathPrefix + path;
|
path = this.pathPrefix + path;
|
||||||
if (!this.queueAsset(clientId, null, path)) return;
|
if (!this.queueAsset(clientId, null, path)) return;
|
||||||
let request = new XMLHttpRequest();
|
let request = new XMLHttpRequest();
|
||||||
request.onreadystatechange = () => {
|
request.onreadystatechange = () => {
|
||||||
if (request.readyState == XMLHttpRequest.DONE) {
|
if (request.readyState == XMLHttpRequest.DONE) {
|
||||||
if (request.status >= 200 && request.status < 300) {
|
if (request.status >= 200 && request.status < 300) {
|
||||||
this.rawAssets[path] = JSON.parse(request.responseText);
|
this.rawAssets[path] = JSON.parse(request.responseText);
|
||||||
} else {
|
} else {
|
||||||
this.errors[path] = `Couldn't load text ${path}: status ${request.status}, ${request.responseText}`;
|
this.errors[path] = `Couldn't load text ${path}: status ${request.status}, ${request.responseText}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,15 +113,15 @@ module spine {
|
|||||||
loadTexture (clientId: string, textureLoader: (image: HTMLImageElement) => any, path: string) {
|
loadTexture (clientId: string, textureLoader: (image: HTMLImageElement) => any, path: string) {
|
||||||
path = this.pathPrefix + path;
|
path = this.pathPrefix + path;
|
||||||
if (!this.queueAsset(clientId, textureLoader, path)) return;
|
if (!this.queueAsset(clientId, textureLoader, path)) return;
|
||||||
|
|
||||||
let img = new Image();
|
let img = new Image();
|
||||||
img.src = path;
|
img.src = path;
|
||||||
img.crossOrigin = "anonymous";
|
img.crossOrigin = "anonymous";
|
||||||
img.onload = (ev) => {
|
img.onload = (ev) => {
|
||||||
this.rawAssets[path] = img;
|
this.rawAssets[path] = img;
|
||||||
}
|
}
|
||||||
img.onerror = (ev) => {
|
img.onerror = (ev) => {
|
||||||
this.errors[path] = `Couldn't load image ${path}`;
|
this.errors[path] = `Couldn't load image ${path}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ module spine {
|
|||||||
path = this.pathPrefix + path;
|
path = this.pathPrefix + path;
|
||||||
var clientAssets = this.clientAssets[clientId];
|
var clientAssets = this.clientAssets[clientId];
|
||||||
if (clientAssets === null || clientAssets === undefined) return true;
|
if (clientAssets === null || clientAssets === undefined) return true;
|
||||||
return clientAssets.assets[path];
|
return clientAssets.assets[path];
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateClientAssets(clientAssets: Assets): void {
|
private updateClientAssets(clientAssets: Assets): void {
|
||||||
@ -151,7 +151,7 @@ module spine {
|
|||||||
isLoadingComplete (clientId: string): boolean {
|
isLoadingComplete (clientId: string): boolean {
|
||||||
var clientAssets = this.clientAssets[clientId];
|
var clientAssets = this.clientAssets[clientId];
|
||||||
if (clientAssets === null || clientAssets === undefined) return true;
|
if (clientAssets === null || clientAssets === undefined) return true;
|
||||||
this.updateClientAssets(clientAssets);
|
this.updateClientAssets(clientAssets);
|
||||||
return clientAssets.toLoad.length == clientAssets.loaded();
|
return clientAssets.toLoad.length == clientAssets.loaded();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -159,7 +159,7 @@ module spine {
|
|||||||
/*remove (clientId: string, path: string) {
|
/*remove (clientId: string, path: string) {
|
||||||
path = this.pathPrefix + path;
|
path = this.pathPrefix + path;
|
||||||
let asset = this.assets[path];
|
let asset = this.assets[path];
|
||||||
if ((<any>asset).dispose) (<any>asset).dispose();
|
if ((<any>asset).dispose) (<any>asset).dispose();
|
||||||
this.assets[path] = null;
|
this.assets[path] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ module spine {
|
|||||||
}
|
}
|
||||||
this.assets = {};
|
this.assets = {};
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
dispose () {
|
dispose () {
|
||||||
// this.removeAll();
|
// this.removeAll();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -183,7 +183,7 @@ module spine {
|
|||||||
|
|
||||||
/** Returns the polygon for the specified bounding box, or null. */
|
/** Returns the polygon for the specified bounding box, or null. */
|
||||||
getPolygon (boundingBox: BoundingBoxAttachment) {
|
getPolygon (boundingBox: BoundingBoxAttachment) {
|
||||||
if (boundingBox == null) throw new Error("boundingBox cannot be null.");
|
if (boundingBox == null) throw new Error("boundingBox cannot be null.");
|
||||||
let index = this.boundingBoxes.indexOf(boundingBox);
|
let index = this.boundingBoxes.indexOf(boundingBox);
|
||||||
return index == -1 ? null : this.polygons[index];
|
return index == -1 ? null : this.polygons[index];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,7 +40,7 @@ module spine {
|
|||||||
|
|
||||||
readSkeletonData (json: string | any ): SkeletonData {
|
readSkeletonData (json: string | any ): SkeletonData {
|
||||||
let scale = this.scale;
|
let scale = this.scale;
|
||||||
let skeletonData = new SkeletonData();
|
let skeletonData = new SkeletonData();
|
||||||
let root = typeof(json) === "string" ? JSON.parse(json) : json;
|
let root = typeof(json) === "string" ? JSON.parse(json) : json;
|
||||||
|
|
||||||
// Skeleton
|
// Skeleton
|
||||||
|
|||||||
@ -47,7 +47,7 @@ module spine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @return May be null. */
|
/** @return May be null. */
|
||||||
getAttachment (slotIndex: number, name: string): Attachment {
|
getAttachment (slotIndex: number, name: string): Attachment {
|
||||||
let dictionary = this.attachments[slotIndex];
|
let dictionary = this.attachments[slotIndex];
|
||||||
return dictionary ? dictionary[name] : null;
|
return dictionary ? dictionary[name] : null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,9 +41,8 @@ module spine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract setFilters (minFilter: TextureFilter, magFilter: TextureFilter): void;
|
abstract setFilters (minFilter: TextureFilter, magFilter: TextureFilter): void;
|
||||||
abstract setWraps (uWrap: TextureWrap, vWrap: TextureWrap): void;
|
abstract setWraps (uWrap: TextureWrap, vWrap: TextureWrap): void;
|
||||||
abstract dispose (): void;
|
abstract dispose (): void;
|
||||||
|
|
||||||
|
|
||||||
public static filterFromString (text: string): TextureFilter {
|
public static filterFromString (text: string): TextureFilter {
|
||||||
switch (text.toLowerCase()) {
|
switch (text.toLowerCase()) {
|
||||||
|
|||||||
@ -78,7 +78,7 @@ module spine {
|
|||||||
|
|
||||||
page.texture = textureLoader(line);
|
page.texture = textureLoader(line);
|
||||||
page.texture.setFilters(page.minFilter, page.magFilter);
|
page.texture.setFilters(page.minFilter, page.magFilter);
|
||||||
page.texture.setWraps(page.uWrap, page.vWrap);
|
page.texture.setWraps(page.uWrap, page.vWrap);
|
||||||
page.width = page.texture.getImage().width;
|
page.width = page.texture.getImage().width;
|
||||||
page.height = page.texture.getImage().height;
|
page.height = page.texture.getImage().height;
|
||||||
this.pages.push(page);
|
this.pages.push(page);
|
||||||
|
|||||||
@ -130,7 +130,7 @@ module spine {
|
|||||||
|
|
||||||
static cbrt (x: number) {
|
static cbrt (x: number) {
|
||||||
var y = Math.pow(Math.abs(x), 1/3);
|
var y = Math.pow(Math.abs(x), 1/3);
|
||||||
return x < 0 ? -y : y;
|
return x < 0 ? -y : y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +235,7 @@ module spine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class TimeKeeper {
|
export class TimeKeeper {
|
||||||
maxDelta = 0.064;
|
maxDelta = 0.064;
|
||||||
framesPerSecond = 0;
|
framesPerSecond = 0;
|
||||||
delta = 0;
|
delta = 0;
|
||||||
totalTime = 0;
|
totalTime = 0;
|
||||||
@ -251,7 +251,7 @@ module spine {
|
|||||||
this.totalTime += this.delta;
|
this.totalTime += this.delta;
|
||||||
if (this.delta > this.maxDelta) this.delta = this.maxDelta;
|
if (this.delta > this.maxDelta) this.delta = this.maxDelta;
|
||||||
this.lastTime = now;
|
this.lastTime = now;
|
||||||
|
|
||||||
this.frameCount++;
|
this.frameCount++;
|
||||||
if (this.frameTime > 1) {
|
if (this.frameTime > 1) {
|
||||||
this.framesPerSecond = this.frameCount / this.frameTime;
|
this.framesPerSecond = this.frameCount / this.frameTime;
|
||||||
|
|||||||
@ -35,7 +35,7 @@ module spine.threejs {
|
|||||||
private static VERTEX_SIZE = 9;
|
private static VERTEX_SIZE = 9;
|
||||||
private vertexBuffer: THREE.InterleavedBuffer;
|
private vertexBuffer: THREE.InterleavedBuffer;
|
||||||
private vertices: Float32Array;
|
private vertices: Float32Array;
|
||||||
private verticesLength = 0;
|
private verticesLength = 0;
|
||||||
private indices: Uint16Array;
|
private indices: Uint16Array;
|
||||||
private indicesLength = 0;
|
private indicesLength = 0;
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ module spine.threejs {
|
|||||||
|
|
||||||
let vertices = this.vertices = new Float32Array(maxVertices * MeshBatcher.VERTEX_SIZE);
|
let vertices = this.vertices = new Float32Array(maxVertices * MeshBatcher.VERTEX_SIZE);
|
||||||
let indices = this.indices = new Uint16Array(maxVertices * 3);
|
let indices = this.indices = new Uint16Array(maxVertices * 3);
|
||||||
this.mesh = mesh;
|
this.mesh = mesh;
|
||||||
let geo = new THREE.BufferGeometry();
|
let geo = new THREE.BufferGeometry();
|
||||||
let vertexBuffer = this.vertexBuffer = new THREE.InterleavedBuffer(vertices, MeshBatcher.VERTEX_SIZE);
|
let vertexBuffer = this.vertexBuffer = new THREE.InterleavedBuffer(vertices, MeshBatcher.VERTEX_SIZE);
|
||||||
vertexBuffer.dynamic = true;
|
vertexBuffer.dynamic = true;
|
||||||
@ -78,13 +78,13 @@ module spine.threejs {
|
|||||||
vertexBuffer[i++] = vertices[j++];
|
vertexBuffer[i++] = vertices[j++];
|
||||||
vertexBuffer[i++] = vertices[j++];
|
vertexBuffer[i++] = vertices[j++];
|
||||||
vertexBuffer[i++] = vertices[j++];
|
vertexBuffer[i++] = vertices[j++];
|
||||||
}
|
}
|
||||||
this.verticesLength = i;
|
this.verticesLength = i;
|
||||||
|
|
||||||
let indicesArray = this.indices;
|
let indicesArray = this.indices;
|
||||||
for (i = this.indicesLength, j = 0; j < indices.length; i++, j++)
|
for (i = this.indicesLength, j = 0; j < indices.length; i++, j++)
|
||||||
indicesArray[i] = indices[j] + indexStart;
|
indicesArray[i] = indices[j] + indexStart;
|
||||||
this.indicesLength += indices.length;
|
this.indicesLength += indices.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
end () {
|
end () {
|
||||||
@ -96,7 +96,7 @@ module spine.threejs {
|
|||||||
geo.getIndex().updateRange.offset = 0;
|
geo.getIndex().updateRange.offset = 0;
|
||||||
geo.getIndex().updateRange.count = this.indicesLength;
|
geo.getIndex().updateRange.count = this.indicesLength;
|
||||||
geo.drawRange.start = 0;
|
geo.drawRange.start = 0;
|
||||||
geo.drawRange.count = this.indicesLength;
|
geo.drawRange.count = this.indicesLength;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,8 +49,8 @@ module spine.threejs {
|
|||||||
let material = this.material = new THREE.MeshBasicMaterial();
|
let material = this.material = new THREE.MeshBasicMaterial();
|
||||||
material.side = THREE.DoubleSide;
|
material.side = THREE.DoubleSide;
|
||||||
material.transparent = true;
|
material.transparent = true;
|
||||||
material.alphaTest = 0.5;
|
material.alphaTest = 0.5;
|
||||||
this.batcher = new MeshBatcher(this);
|
this.batcher = new MeshBatcher(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
update(deltaTime: number) {
|
update(deltaTime: number) {
|
||||||
@ -69,11 +69,11 @@ module spine.threejs {
|
|||||||
var numVertices = 0;
|
var numVertices = 0;
|
||||||
var verticesLength = 0;
|
var verticesLength = 0;
|
||||||
var indicesLength = 0;
|
var indicesLength = 0;
|
||||||
|
|
||||||
let blendMode: BlendMode = null;
|
let blendMode: BlendMode = null;
|
||||||
|
|
||||||
let vertices: ArrayLike<number> = null;
|
let vertices: ArrayLike<number> = null;
|
||||||
let triangles: Array<number> = null;
|
let triangles: Array<number> = null;
|
||||||
let drawOrder = this.skeleton.drawOrder;
|
let drawOrder = this.skeleton.drawOrder;
|
||||||
let batcher = this.batcher;
|
let batcher = this.batcher;
|
||||||
batcher.begin();
|
batcher.begin();
|
||||||
@ -98,19 +98,19 @@ module spine.threejs {
|
|||||||
|
|
||||||
if (texture != null) {
|
if (texture != null) {
|
||||||
if (!(<THREE.MeshBasicMaterial>this.material).map) {
|
if (!(<THREE.MeshBasicMaterial>this.material).map) {
|
||||||
let mat = <THREE.MeshBasicMaterial>this.material;
|
let mat = <THREE.MeshBasicMaterial>this.material;
|
||||||
mat.map = texture.texture;
|
mat.map = texture.texture;
|
||||||
mat.needsUpdate = true;
|
mat.needsUpdate = true;
|
||||||
}
|
}
|
||||||
// FIXME per slot blending would require multiple material support
|
// FIXME per slot blending would require multiple material support
|
||||||
//let slotBlendMode = slot.data.blendMode;
|
//let slotBlendMode = slot.data.blendMode;
|
||||||
//if (slotBlendMode != blendMode) {
|
//if (slotBlendMode != blendMode) {
|
||||||
// blendMode = slotBlendMode;
|
// blendMode = slotBlendMode;
|
||||||
// batcher.setBlendMode(getSourceGLBlendMode(this._gl, blendMode, premultipliedAlpha), getDestGLBlendMode(this._gl, blendMode));
|
// batcher.setBlendMode(getSourceGLBlendMode(this._gl, blendMode, premultipliedAlpha), getDestGLBlendMode(this._gl, blendMode));
|
||||||
//}
|
//}
|
||||||
|
|
||||||
this.batcher.batch(vertices, triangles, z);
|
this.batcher.batch(vertices, triangles, z);
|
||||||
z += zOffset;
|
z += zOffset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ module spine.threejs {
|
|||||||
let mat = new THREE.MeshBasicMaterial();
|
let mat = new THREE.MeshBasicMaterial();
|
||||||
mat.vertexColors = THREE.VertexColors;
|
mat.vertexColors = THREE.VertexColors;
|
||||||
mat.transparent = true;
|
mat.transparent = true;
|
||||||
mat.map = map;
|
mat.map = map;
|
||||||
let mesh = new THREE.Mesh(geo, mat);
|
let mesh = new THREE.Mesh(geo, mat);
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,7 +55,7 @@ module spine.threejs {
|
|||||||
|
|
||||||
static toThreeJsTextureFilter(filter: TextureFilter) {
|
static toThreeJsTextureFilter(filter: TextureFilter) {
|
||||||
if (filter === TextureFilter.Linear) return THREE.LinearFilter;
|
if (filter === TextureFilter.Linear) return THREE.LinearFilter;
|
||||||
else if (filter === TextureFilter.MipMap) return THREE.LinearMipMapLinearFilter; // also includes TextureFilter.MipMapLinearLinear
|
else if (filter === TextureFilter.MipMap) return THREE.LinearMipMapLinearFilter; // also includes TextureFilter.MipMapLinearLinear
|
||||||
else if (filter === TextureFilter.MipMapLinearNearest) return THREE.LinearMipMapNearestFilter;
|
else if (filter === TextureFilter.MipMapLinearNearest) return THREE.LinearMipMapNearestFilter;
|
||||||
else if (filter === TextureFilter.MipMapNearestLinear) return THREE.NearestMipMapLinearFilter;
|
else if (filter === TextureFilter.MipMapNearestLinear) return THREE.NearestMipMapLinearFilter;
|
||||||
else if (filter === TextureFilter.MipMapNearestNearest) return THREE.NearestMipMapNearestFilter;
|
else if (filter === TextureFilter.MipMapNearestNearest) return THREE.NearestMipMapNearestFilter;
|
||||||
|
|||||||
@ -37,11 +37,11 @@ module spine.webgl {
|
|||||||
far = 100;
|
far = 100;
|
||||||
zoom = 1;
|
zoom = 1;
|
||||||
viewportWidth = 0;
|
viewportWidth = 0;
|
||||||
viewportHeight = 0;
|
viewportHeight = 0;
|
||||||
projectionView = new Matrix4();
|
projectionView = new Matrix4();
|
||||||
inverseProjectionView = new Matrix4();
|
inverseProjectionView = new Matrix4();
|
||||||
projection = new Matrix4();
|
projection = new Matrix4();
|
||||||
view = new Matrix4();
|
view = new Matrix4();
|
||||||
|
|
||||||
private tmp = new Vector3();
|
private tmp = new Vector3();
|
||||||
|
|
||||||
@ -56,22 +56,22 @@ module spine.webgl {
|
|||||||
let view = this.view;
|
let view = this.view;
|
||||||
let projectionView = this.projectionView;
|
let projectionView = this.projectionView;
|
||||||
let inverseProjectionView = this.inverseProjectionView;
|
let inverseProjectionView = this.inverseProjectionView;
|
||||||
let zoom = this.zoom, viewportWidth = this.viewportWidth, viewportHeight = this.viewportHeight;
|
let zoom = this.zoom, viewportWidth = this.viewportWidth, viewportHeight = this.viewportHeight;
|
||||||
projection.ortho(zoom * (-viewportWidth / 2), zoom * (viewportWidth / 2),
|
projection.ortho(zoom * (-viewportWidth / 2), zoom * (viewportWidth / 2),
|
||||||
zoom * (-viewportHeight / 2), zoom * (viewportHeight / 2),
|
zoom * (-viewportHeight / 2), zoom * (viewportHeight / 2),
|
||||||
this.near, this.far);
|
this.near, this.far);
|
||||||
view.lookAt(this.position, this.direction, this.up);
|
view.lookAt(this.position, this.direction, this.up);
|
||||||
projectionView.set(projection.values);
|
projectionView.set(projection.values);
|
||||||
projectionView.multiply(view);
|
projectionView.multiply(view);
|
||||||
inverseProjectionView.set(projectionView.values).invert();
|
inverseProjectionView.set(projectionView.values).invert();
|
||||||
}
|
}
|
||||||
|
|
||||||
screenToWorld (screenCoords: Vector3, screenWidth: number, screenHeight: number) {
|
screenToWorld (screenCoords: Vector3, screenWidth: number, screenHeight: number) {
|
||||||
let x = screenCoords.x, y = screenHeight - screenCoords.y - 1;
|
let x = screenCoords.x, y = screenHeight - screenCoords.y - 1;
|
||||||
let tmp = this.tmp;
|
let tmp = this.tmp;
|
||||||
tmp.x = (2 * x) / screenWidth - 1;
|
tmp.x = (2 * x) / screenWidth - 1;
|
||||||
tmp.y = (2 * y) / screenHeight - 1;
|
tmp.y = (2 * y) / screenHeight - 1;
|
||||||
tmp.z = (2 * screenCoords.z) - 1;
|
tmp.z = (2 * screenCoords.z) - 1;
|
||||||
tmp.project(this.inverseProjectionView);
|
tmp.project(this.inverseProjectionView);
|
||||||
screenCoords.set(tmp.x, tmp.y, tmp.z);
|
screenCoords.set(tmp.x, tmp.y, tmp.z);
|
||||||
return screenCoords;
|
return screenCoords;
|
||||||
|
|||||||
@ -31,13 +31,13 @@
|
|||||||
module spine.webgl {
|
module spine.webgl {
|
||||||
export class GLTexture extends Texture implements Disposable {
|
export class GLTexture extends Texture implements Disposable {
|
||||||
private gl: WebGLRenderingContext;
|
private gl: WebGLRenderingContext;
|
||||||
private texture: WebGLTexture;
|
private texture: WebGLTexture;
|
||||||
private boundUnit = 0;
|
private boundUnit = 0;
|
||||||
|
|
||||||
constructor (gl: WebGLRenderingContext, image: HTMLImageElement, useMipMaps: boolean = false) {
|
constructor (gl: WebGLRenderingContext, image: HTMLImageElement, useMipMaps: boolean = false) {
|
||||||
super(image);
|
super(image);
|
||||||
this.gl = gl;
|
this.gl = gl;
|
||||||
this.texture = gl.createTexture();
|
this.texture = gl.createTexture();
|
||||||
this.update(useMipMaps);
|
this.update(useMipMaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -50,7 +50,7 @@ module spine.webgl {
|
|||||||
if (ev instanceof MouseEvent) {
|
if (ev instanceof MouseEvent) {
|
||||||
let rect = element.getBoundingClientRect();
|
let rect = element.getBoundingClientRect();
|
||||||
let x = ev.clientX - rect.left;
|
let x = ev.clientX - rect.left;
|
||||||
let y = ev.clientY - rect.top;
|
let y = ev.clientY - rect.top;
|
||||||
|
|
||||||
let listeners = this.listeners;
|
let listeners = this.listeners;
|
||||||
for (let i = 0; i < listeners.length; i++) {
|
for (let i = 0; i < listeners.length; i++) {
|
||||||
@ -66,7 +66,7 @@ module spine.webgl {
|
|||||||
if (ev instanceof MouseEvent) {
|
if (ev instanceof MouseEvent) {
|
||||||
let rect = element.getBoundingClientRect();
|
let rect = element.getBoundingClientRect();
|
||||||
let x = ev.clientX - rect.left;
|
let x = ev.clientX - rect.left;
|
||||||
let y = ev.clientY - rect.top;
|
let y = ev.clientY - rect.top;
|
||||||
|
|
||||||
let listeners = this.listeners;
|
let listeners = this.listeners;
|
||||||
for (let i = 0; i < listeners.length; i++) {
|
for (let i = 0; i < listeners.length; i++) {
|
||||||
@ -78,14 +78,14 @@ module spine.webgl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.lastX = x;
|
this.lastX = x;
|
||||||
this.lastY = y;
|
this.lastY = y;
|
||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
element.addEventListener("mouseup", (ev: UIEvent) => {
|
element.addEventListener("mouseup", (ev: UIEvent) => {
|
||||||
if (ev instanceof MouseEvent) {
|
if (ev instanceof MouseEvent) {
|
||||||
let rect = element.getBoundingClientRect();
|
let rect = element.getBoundingClientRect();
|
||||||
let x = ev.clientX - rect.left;
|
let x = ev.clientX - rect.left;
|
||||||
let y = ev.clientY - rect.top;
|
let y = ev.clientY - rect.top;
|
||||||
|
|
||||||
let listeners = this.listeners;
|
let listeners = this.listeners;
|
||||||
for (let i = 0; i < listeners.length; i++) {
|
for (let i = 0; i < listeners.length; i++) {
|
||||||
@ -97,12 +97,12 @@ module spine.webgl {
|
|||||||
this.buttonDown = false;
|
this.buttonDown = false;
|
||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
element.addEventListener("touchstart", (ev: TouchEvent) => {
|
element.addEventListener("touchstart", (ev: TouchEvent) => {
|
||||||
if (this.currTouch != null) return;
|
if (this.currTouch != null) return;
|
||||||
|
|
||||||
var touches = ev.changedTouches;
|
var touches = ev.changedTouches;
|
||||||
for (var i = 0; i < touches.length; i++) {
|
for (var i = 0; i < touches.length; i++) {
|
||||||
var touch = touches[i];
|
var touch = touches[i];
|
||||||
let rect = element.getBoundingClientRect();
|
let rect = element.getBoundingClientRect();
|
||||||
let x = touch.clientX - rect.left;
|
let x = touch.clientX - rect.left;
|
||||||
let y = touch.clientY - rect.top;
|
let y = touch.clientY - rect.top;
|
||||||
@ -111,7 +111,7 @@ module spine.webgl {
|
|||||||
this.currTouch.x = x;
|
this.currTouch.x = x;
|
||||||
this.currTouch.y = y;
|
this.currTouch.y = y;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let listeners = this.listeners;
|
let listeners = this.listeners;
|
||||||
for (let i = 0; i < listeners.length; i++) {
|
for (let i = 0; i < listeners.length; i++) {
|
||||||
@ -130,7 +130,7 @@ module spine.webgl {
|
|||||||
if (this.currTouch.identifier === touch.identifier) {
|
if (this.currTouch.identifier === touch.identifier) {
|
||||||
let rect = element.getBoundingClientRect();
|
let rect = element.getBoundingClientRect();
|
||||||
let x = this.currTouch.x = touch.clientX - rect.left;
|
let x = this.currTouch.x = touch.clientX - rect.left;
|
||||||
let y = this.currTouch.y = touch.clientY - rect.top;
|
let y = this.currTouch.y = touch.clientY - rect.top;
|
||||||
this.touchesPool.free(this.currTouch);
|
this.touchesPool.free(this.currTouch);
|
||||||
let listeners = this.listeners;
|
let listeners = this.listeners;
|
||||||
for (let i = 0; i < listeners.length; i++) {
|
for (let i = 0; i < listeners.length; i++) {
|
||||||
@ -146,14 +146,14 @@ module spine.webgl {
|
|||||||
}
|
}
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
}, false);
|
}, false);
|
||||||
element.addEventListener("touchcancel", (ev: TouchEvent) => {
|
element.addEventListener("touchcancel", (ev: TouchEvent) => {
|
||||||
var touches = ev.changedTouches;
|
var touches = ev.changedTouches;
|
||||||
for (var i = 0; i < touches.length; i++) {
|
for (var i = 0; i < touches.length; i++) {
|
||||||
var touch = touches[i];
|
var touch = touches[i];
|
||||||
if (this.currTouch.identifier === touch.identifier) {
|
if (this.currTouch.identifier === touch.identifier) {
|
||||||
let rect = element.getBoundingClientRect();
|
let rect = element.getBoundingClientRect();
|
||||||
let x = this.currTouch.x = touch.clientX - rect.left;
|
let x = this.currTouch.x = touch.clientX - rect.left;
|
||||||
let y = this.currTouch.y = touch.clientY - rect.top;
|
let y = this.currTouch.y = touch.clientY - rect.top;
|
||||||
this.touchesPool.free(this.currTouch);
|
this.touchesPool.free(this.currTouch);
|
||||||
let listeners = this.listeners;
|
let listeners = this.listeners;
|
||||||
for (let i = 0; i < listeners.length; i++) {
|
for (let i = 0; i < listeners.length; i++) {
|
||||||
@ -169,7 +169,7 @@ module spine.webgl {
|
|||||||
}
|
}
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
}, false);
|
}, false);
|
||||||
element.addEventListener("touchmove", (ev: TouchEvent) => {
|
element.addEventListener("touchmove", (ev: TouchEvent) => {
|
||||||
if (this.currTouch == null) return;
|
if (this.currTouch == null) return;
|
||||||
|
|
||||||
var touches = ev.changedTouches;
|
var touches = ev.changedTouches;
|
||||||
@ -178,7 +178,7 @@ module spine.webgl {
|
|||||||
if (this.currTouch.identifier === touch.identifier) {
|
if (this.currTouch.identifier === touch.identifier) {
|
||||||
let rect = element.getBoundingClientRect();
|
let rect = element.getBoundingClientRect();
|
||||||
let x = touch.clientX - rect.left;
|
let x = touch.clientX - rect.left;
|
||||||
let y = touch.clientY - rect.top;
|
let y = touch.clientY - rect.top;
|
||||||
|
|
||||||
let listeners = this.listeners;
|
let listeners = this.listeners;
|
||||||
for (let i = 0; i < listeners.length; i++) {
|
for (let i = 0; i < listeners.length; i++) {
|
||||||
@ -207,7 +207,7 @@ module spine.webgl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Touch {
|
export class Touch {
|
||||||
constructor(public identifier: number, public x: number, public y: number) {
|
constructor(public identifier: number, public x: number, public y: number) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -59,7 +59,7 @@ module spine.webgl {
|
|||||||
// thank you Apple Inc.
|
// thank you Apple Inc.
|
||||||
let isSafari = navigator.userAgent.indexOf("Safari") > -1;
|
let isSafari = navigator.userAgent.indexOf("Safari") > -1;
|
||||||
|
|
||||||
LoadingScreen.logoImg = new Image();
|
LoadingScreen.logoImg = new Image();
|
||||||
LoadingScreen.logoImg.src = LoadingScreen.SPINE_LOGO_DATA;
|
LoadingScreen.logoImg.src = LoadingScreen.SPINE_LOGO_DATA;
|
||||||
if (!isSafari) LoadingScreen.logoImg.crossOrigin = "anonymous";
|
if (!isSafari) LoadingScreen.logoImg.crossOrigin = "anonymous";
|
||||||
LoadingScreen.logoImg.onload = (ev) => {
|
LoadingScreen.logoImg.onload = (ev) => {
|
||||||
@ -68,7 +68,7 @@ module spine.webgl {
|
|||||||
|
|
||||||
LoadingScreen.spinnerImg = new Image();
|
LoadingScreen.spinnerImg = new Image();
|
||||||
LoadingScreen.spinnerImg.src = LoadingScreen.SPINNER_DATA;
|
LoadingScreen.spinnerImg.src = LoadingScreen.SPINNER_DATA;
|
||||||
if (!isSafari) LoadingScreen.spinnerImg.crossOrigin = "anonymous";
|
if (!isSafari) LoadingScreen.spinnerImg.crossOrigin = "anonymous";
|
||||||
LoadingScreen.spinnerImg.onload = (ev) => {
|
LoadingScreen.spinnerImg.onload = (ev) => {
|
||||||
LoadingScreen.loaded++;
|
LoadingScreen.loaded++;
|
||||||
}
|
}
|
||||||
@ -115,7 +115,7 @@ module spine.webgl {
|
|||||||
if (LoadingScreen.loaded != 2) return;
|
if (LoadingScreen.loaded != 2) return;
|
||||||
if (this.logo === null) {
|
if (this.logo === null) {
|
||||||
this.logo = new GLTexture(renderer.gl, LoadingScreen.logoImg);
|
this.logo = new GLTexture(renderer.gl, LoadingScreen.logoImg);
|
||||||
this.spinner = new GLTexture(renderer.gl, LoadingScreen.spinnerImg);
|
this.spinner = new GLTexture(renderer.gl, LoadingScreen.spinnerImg);
|
||||||
}
|
}
|
||||||
this.logo.update(false);
|
this.logo.update(false);
|
||||||
this.spinner.update(false);
|
this.spinner.update(false);
|
||||||
@ -127,7 +127,7 @@ module spine.webgl {
|
|||||||
|
|
||||||
renderer.batcher.setBlendMode(WebGLRenderingContext.SRC_ALPHA, WebGLRenderingContext.ONE_MINUS_SRC_ALPHA);
|
renderer.batcher.setBlendMode(WebGLRenderingContext.SRC_ALPHA, WebGLRenderingContext.ONE_MINUS_SRC_ALPHA);
|
||||||
renderer.begin();
|
renderer.begin();
|
||||||
renderer.drawTexture(this.logo, (canvas.width - logoWidth) / 2, (canvas.height - logoHeight) / 2, logoWidth, logoHeight, this.tempColor);
|
renderer.drawTexture(this.logo, (canvas.width - logoWidth) / 2, (canvas.height - logoHeight) / 2, logoWidth, logoHeight, this.tempColor);
|
||||||
renderer.drawTextureRotated(this.spinner, (canvas.width - spinnerWidth) / 2, (canvas.height - spinnerHeight) / 2, spinnerWidth, spinnerHeight, spinnerWidth / 2, spinnerHeight / 2, this.angle, this.tempColor);
|
renderer.drawTextureRotated(this.spinner, (canvas.width - spinnerWidth) / 2, (canvas.height - spinnerHeight) / 2, spinnerWidth, spinnerHeight, spinnerWidth / 2, spinnerHeight / 2, this.angle, this.tempColor);
|
||||||
renderer.end();
|
renderer.end();
|
||||||
|
|
||||||
|
|||||||
@ -49,7 +49,7 @@ module spine.webgl {
|
|||||||
export class Matrix4 {
|
export class Matrix4 {
|
||||||
temp: Float32Array = new Float32Array(16);
|
temp: Float32Array = new Float32Array(16);
|
||||||
values: Float32Array = new Float32Array(16);
|
values: Float32Array = new Float32Array(16);
|
||||||
|
|
||||||
private static xAxis: Vector3 = null;
|
private static xAxis: Vector3 = null;
|
||||||
private static yAxis: Vector3 = null;
|
private static yAxis: Vector3 = null;
|
||||||
private static zAxis: Vector3 = null;
|
private static zAxis: Vector3 = null;
|
||||||
|
|||||||
@ -34,7 +34,7 @@ module spine.webgl {
|
|||||||
private drawCalls: number;
|
private drawCalls: number;
|
||||||
private isDrawing = false;
|
private isDrawing = false;
|
||||||
private mesh: Mesh;
|
private mesh: Mesh;
|
||||||
private shader: Shader = null;
|
private shader: Shader = null;
|
||||||
private lastTexture: GLTexture = null;
|
private lastTexture: GLTexture = null;
|
||||||
private verticesLength = 0;
|
private verticesLength = 0;
|
||||||
private indicesLength = 0;
|
private indicesLength = 0;
|
||||||
@ -44,10 +44,10 @@ module spine.webgl {
|
|||||||
constructor (gl: WebGLRenderingContext, maxVertices: number = 10920) {
|
constructor (gl: WebGLRenderingContext, maxVertices: number = 10920) {
|
||||||
if (maxVertices > 10920) throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
|
if (maxVertices > 10920) throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
|
||||||
this.gl = gl;
|
this.gl = gl;
|
||||||
this.mesh = new Mesh(gl, [new Position2Attribute(), new ColorAttribute(), new TexCoordAttribute()], maxVertices, maxVertices * 3);
|
this.mesh = new Mesh(gl, [new Position2Attribute(), new ColorAttribute(), new TexCoordAttribute()], maxVertices, maxVertices * 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
begin (shader: Shader) {
|
begin (shader: Shader) {
|
||||||
let gl = this.gl;
|
let gl = this.gl;
|
||||||
if (this.isDrawing) throw new Error("PolygonBatch is already drawing. Call PolygonBatch.end() before calling PolygonBatch.begin()");
|
if (this.isDrawing) throw new Error("PolygonBatch is already drawing. Call PolygonBatch.end() before calling PolygonBatch.begin()");
|
||||||
this.drawCalls = 0;
|
this.drawCalls = 0;
|
||||||
@ -118,7 +118,7 @@ module spine.webgl {
|
|||||||
getDrawCalls () { return this.drawCalls; }
|
getDrawCalls () { return this.drawCalls; }
|
||||||
|
|
||||||
dispose () {
|
dispose () {
|
||||||
this.mesh.dispose();
|
this.mesh.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user