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