Every space in its place! (tm)

(whitespace clean up)
This commit is contained in:
NathanSweet 2016-10-15 23:15:41 +02:00
parent ded7a697d9
commit 7a18f0818c
106 changed files with 2314 additions and 2316 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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 {

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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, ...

View File

@ -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) {

View File

@ -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];
} }
} }

View File

@ -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;

View File

@ -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.");

View File

@ -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];

View File

@ -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];

View File

@ -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];

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;

View File

@ -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) {

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;
} }

View File

@ -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);
} }

View File

@ -1,7 +1,7 @@
application = { application = {
content = { content = {
width = 320, width = 320,
height = 480, height = 480,
scale = "letterBox", scale = "letterBox",
fps = 60, fps = 60,
}, },

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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);

View File

@ -43,6 +43,6 @@ namespace Spine {
public PathAttachment (String name) public PathAttachment (String name)
: base(name) { : base(name) {
} }
} }
} }

View File

@ -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;

View File

@ -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;
} }
} }
} }

View File

@ -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;

View File

@ -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
} }

View File

@ -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];

View File

@ -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;

View File

@ -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 {

View File

@ -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.");

View File

@ -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]);
} }

View File

@ -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;

View File

@ -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);
} }

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
} }

View File

@ -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));

View File

@ -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;
} }

View File

@ -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;
} }
} }

View File

@ -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);
} }

View File

@ -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);

View File

@ -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);

View File

@ -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();
} }
} }
} }

View File

@ -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 () {

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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();
} }

View File

@ -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];
} }

View File

@ -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

View File

@ -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;
} }

View File

@ -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()) {

View File

@ -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);

View File

@ -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;

View File

@ -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;
} }
} }
} }

View File

@ -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;
} }

View File

@ -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;

View File

@ -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;

View File

@ -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);
} }

View File

@ -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) {
} }
} }

View File

@ -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();

View File

@ -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;

View File

@ -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