@esotericsoftware/spine-webgl
Version:
The official Spine Runtimes for the web.
1,762 lines (1,759 loc) • 520 kB
JavaScript
// spine-core/src/Utils.ts
var IntSet = class {
array = new Array();
add(value) {
let contains = this.contains(value);
this.array[value | 0] = value | 0;
return !contains;
}
contains(value) {
return this.array[value | 0] != void 0;
}
remove(value) {
this.array[value | 0] = void 0;
}
clear() {
this.array.length = 0;
}
};
var StringSet = class {
entries = {};
size = 0;
add(value) {
let contains = this.entries[value];
this.entries[value] = true;
if (!contains) {
this.size++;
return true;
}
return false;
}
addAll(values) {
let oldSize = this.size;
for (var i = 0, n = values.length; i < n; i++)
this.add(values[i]);
return oldSize != this.size;
}
contains(value) {
return this.entries[value];
}
clear() {
this.entries = {};
this.size = 0;
}
};
var Color = class _Color {
constructor(r = 0, g = 0, b = 0, a = 0) {
this.r = r;
this.g = g;
this.b = b;
this.a = a;
}
static WHITE = new _Color(1, 1, 1, 1);
static RED = new _Color(1, 0, 0, 1);
static GREEN = new _Color(0, 1, 0, 1);
static BLUE = new _Color(0, 0, 1, 1);
static MAGENTA = new _Color(1, 0, 1, 1);
set(r, g, b, a) {
this.r = r;
this.g = g;
this.b = b;
this.a = a;
return this.clamp();
}
setFromColor(c) {
this.r = c.r;
this.g = c.g;
this.b = c.b;
this.a = c.a;
return this;
}
setFromString(hex) {
hex = hex.charAt(0) == "#" ? hex.substr(1) : hex;
this.r = parseInt(hex.substr(0, 2), 16) / 255;
this.g = parseInt(hex.substr(2, 2), 16) / 255;
this.b = parseInt(hex.substr(4, 2), 16) / 255;
this.a = hex.length != 8 ? 1 : parseInt(hex.substr(6, 2), 16) / 255;
return this;
}
add(r, g, b, a) {
this.r += r;
this.g += g;
this.b += b;
this.a += a;
return this.clamp();
}
clamp() {
if (this.r < 0) this.r = 0;
else if (this.r > 1) this.r = 1;
if (this.g < 0) this.g = 0;
else if (this.g > 1) this.g = 1;
if (this.b < 0) this.b = 0;
else if (this.b > 1) this.b = 1;
if (this.a < 0) this.a = 0;
else if (this.a > 1) this.a = 1;
return this;
}
static rgba8888ToColor(color, value) {
color.r = ((value & 4278190080) >>> 24) / 255;
color.g = ((value & 16711680) >>> 16) / 255;
color.b = ((value & 65280) >>> 8) / 255;
color.a = (value & 255) / 255;
}
static rgb888ToColor(color, value) {
color.r = ((value & 16711680) >>> 16) / 255;
color.g = ((value & 65280) >>> 8) / 255;
color.b = (value & 255) / 255;
}
toRgb888() {
const hex = (x) => ("0" + (x * 255).toString(16)).slice(-2);
return Number("0x" + hex(this.r) + hex(this.g) + hex(this.b));
}
static fromString(hex, color = new _Color()) {
return color.setFromString(hex);
}
};
var MathUtils = class _MathUtils {
static PI = 3.1415927;
static PI2 = _MathUtils.PI * 2;
static invPI2 = 1 / _MathUtils.PI2;
static radiansToDegrees = 180 / _MathUtils.PI;
static radDeg = _MathUtils.radiansToDegrees;
static degreesToRadians = _MathUtils.PI / 180;
static degRad = _MathUtils.degreesToRadians;
static clamp(value, min, max) {
if (value < min) return min;
if (value > max) return max;
return value;
}
static cosDeg(degrees) {
return Math.cos(degrees * _MathUtils.degRad);
}
static sinDeg(degrees) {
return Math.sin(degrees * _MathUtils.degRad);
}
static atan2Deg(y, x) {
return Math.atan2(y, x) * _MathUtils.degRad;
}
static signum(value) {
return value > 0 ? 1 : value < 0 ? -1 : 0;
}
static toInt(x) {
return x > 0 ? Math.floor(x) : Math.ceil(x);
}
static cbrt(x) {
let y = Math.pow(Math.abs(x), 1 / 3);
return x < 0 ? -y : y;
}
static randomTriangular(min, max) {
return _MathUtils.randomTriangularWith(min, max, (min + max) * 0.5);
}
static randomTriangularWith(min, max, mode) {
let u = Math.random();
let d = max - min;
if (u <= (mode - min) / d) return min + Math.sqrt(u * d * (mode - min));
return max - Math.sqrt((1 - u) * d * (max - mode));
}
static isPowerOfTwo(value) {
return value && (value & value - 1) === 0;
}
};
var Interpolation = class {
apply(start, end, a) {
return start + (end - start) * this.applyInternal(a);
}
};
var Pow = class extends Interpolation {
power = 2;
constructor(power) {
super();
this.power = power;
}
applyInternal(a) {
if (a <= 0.5) return Math.pow(a * 2, this.power) / 2;
return Math.pow((a - 1) * 2, this.power) / (this.power % 2 == 0 ? -2 : 2) + 1;
}
};
var PowOut = class extends Pow {
constructor(power) {
super(power);
}
applyInternal(a) {
return Math.pow(a - 1, this.power) * (this.power % 2 == 0 ? -1 : 1) + 1;
}
};
var Utils = class _Utils {
static SUPPORTS_TYPED_ARRAYS = typeof Float32Array !== "undefined";
static arrayCopy(source, sourceStart, dest, destStart, numElements) {
for (let i = sourceStart, j = destStart; i < sourceStart + numElements; i++, j++) {
dest[j] = source[i];
}
}
static arrayFill(array, fromIndex, toIndex, value) {
for (let i = fromIndex; i < toIndex; i++)
array[i] = value;
}
static setArraySize(array, size, value = 0) {
let oldSize = array.length;
if (oldSize == size) return array;
array.length = size;
if (oldSize < size) {
for (let i = oldSize; i < size; i++) array[i] = value;
}
return array;
}
static ensureArrayCapacity(array, size, value = 0) {
if (array.length >= size) return array;
return _Utils.setArraySize(array, size, value);
}
static newArray(size, defaultValue) {
let array = new Array(size);
for (let i = 0; i < size; i++) array[i] = defaultValue;
return array;
}
static newFloatArray(size) {
if (_Utils.SUPPORTS_TYPED_ARRAYS)
return new Float32Array(size);
else {
let array = new Array(size);
for (let i = 0; i < array.length; i++) array[i] = 0;
return array;
}
}
static newShortArray(size) {
if (_Utils.SUPPORTS_TYPED_ARRAYS)
return new Int16Array(size);
else {
let array = new Array(size);
for (let i = 0; i < array.length; i++) array[i] = 0;
return array;
}
}
static toFloatArray(array) {
return _Utils.SUPPORTS_TYPED_ARRAYS ? new Float32Array(array) : array;
}
static toSinglePrecision(value) {
return _Utils.SUPPORTS_TYPED_ARRAYS ? Math.fround(value) : value;
}
// This function is used to fix WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109
static webkit602BugfixHelper(alpha, blend) {
}
static contains(array, element, identity = true) {
for (var i = 0; i < array.length; i++)
if (array[i] == element) return true;
return false;
}
static enumValue(type, name) {
return type[name[0].toUpperCase() + name.slice(1)];
}
};
var DebugUtils = class {
static logBones(skeleton) {
for (let i = 0; i < skeleton.bones.length; i++) {
let bone = skeleton.bones[i];
console.log(bone.data.name + ", " + bone.a + ", " + bone.b + ", " + bone.c + ", " + bone.d + ", " + bone.worldX + ", " + bone.worldY);
}
}
};
var Pool = class {
items = new Array();
instantiator;
constructor(instantiator) {
this.instantiator = instantiator;
}
obtain() {
return this.items.length > 0 ? this.items.pop() : this.instantiator();
}
free(item) {
if (item.reset) item.reset();
this.items.push(item);
}
freeAll(items) {
for (let i = 0; i < items.length; i++)
this.free(items[i]);
}
clear() {
this.items.length = 0;
}
};
var Vector2 = class {
constructor(x = 0, y = 0) {
this.x = x;
this.y = y;
}
set(x, y) {
this.x = x;
this.y = y;
return this;
}
length() {
let x = this.x;
let y = this.y;
return Math.sqrt(x * x + y * y);
}
normalize() {
let len = this.length();
if (len != 0) {
this.x /= len;
this.y /= len;
}
return this;
}
};
var TimeKeeper = class {
maxDelta = 0.064;
framesPerSecond = 0;
delta = 0;
totalTime = 0;
lastTime = Date.now() / 1e3;
frameCount = 0;
frameTime = 0;
update() {
let now = Date.now() / 1e3;
this.delta = now - this.lastTime;
this.frameTime += this.delta;
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;
this.frameTime = 0;
this.frameCount = 0;
}
}
};
var WindowedMean = class {
values;
addedValues = 0;
lastValue = 0;
mean = 0;
dirty = true;
constructor(windowSize = 32) {
this.values = new Array(windowSize);
}
hasEnoughData() {
return this.addedValues >= this.values.length;
}
addValue(value) {
if (this.addedValues < this.values.length) this.addedValues++;
this.values[this.lastValue++] = value;
if (this.lastValue > this.values.length - 1) this.lastValue = 0;
this.dirty = true;
}
getMean() {
if (this.hasEnoughData()) {
if (this.dirty) {
let mean = 0;
for (let i = 0; i < this.values.length; i++)
mean += this.values[i];
this.mean = mean / this.values.length;
this.dirty = false;
}
return this.mean;
}
return 0;
}
};
// spine-core/src/attachments/Attachment.ts
var Attachment = class {
name;
constructor(name) {
if (!name) throw new Error("name cannot be null.");
this.name = name;
}
};
var VertexAttachment = class _VertexAttachment extends Attachment {
static nextID = 0;
/** The unique ID for this attachment. */
id = _VertexAttachment.nextID++;
/** The bones which affect the {@link #getVertices()}. The array entries are, for each vertex, the number of bones affecting
* the vertex followed by that many bone indices, which is the index of the bone in {@link Skeleton#bones}. Will be null
* if this attachment has no weights. */
bones = null;
/** The vertex positions in the bone's coordinate system. For a non-weighted attachment, the values are `x,y`
* entries for each vertex. For a weighted attachment, the values are `x,y,weight` entries for each bone affecting
* each vertex. */
vertices = [];
/** The maximum number of world vertex values that can be output by
* {@link #computeWorldVertices()} using the `count` parameter. */
worldVerticesLength = 0;
/** Timelines for the timeline attachment are also applied to this attachment.
* May be null if no attachment-specific timelines should be applied. */
timelineAttachment = this;
constructor(name) {
super(name);
}
/** Transforms the attachment's local {@link #vertices} to world coordinates. If the slot's {@link Slot#deform} is
* not empty, it is used to deform the vertices.
*
* See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine
* Runtimes Guide.
* @param start The index of the first {@link #vertices} value to transform. Each vertex has 2 values, x and y.
* @param count The number of world vertex values to output. Must be <= {@link #worldVerticesLength} - `start`.
* @param worldVertices The output world vertices. Must have a length >= `offset` + `count` *
* `stride` / 2.
* @param offset The `worldVertices` index to begin writing values.
* @param stride The number of `worldVertices` entries between the value pairs written. */
computeWorldVertices(slot, start, count, worldVertices, offset, stride) {
count = offset + (count >> 1) * stride;
let skeleton = slot.bone.skeleton;
let deformArray = slot.deform;
let vertices = this.vertices;
let bones = this.bones;
if (!bones) {
if (deformArray.length > 0) vertices = deformArray;
let bone = slot.bone;
let x = bone.worldX;
let y = bone.worldY;
let a = bone.a, b = bone.b, c = bone.c, d = bone.d;
for (let v2 = start, w = offset; w < count; v2 += 2, w += stride) {
let vx = vertices[v2], vy = vertices[v2 + 1];
worldVertices[w] = vx * a + vy * b + x;
worldVertices[w + 1] = vx * c + vy * d + y;
}
return;
}
let v = 0, skip = 0;
for (let i = 0; i < start; i += 2) {
let n = bones[v];
v += n + 1;
skip += n;
}
let skeletonBones = skeleton.bones;
if (deformArray.length == 0) {
for (let w = offset, b = skip * 3; w < count; w += stride) {
let wx = 0, wy = 0;
let n = bones[v++];
n += v;
for (; v < n; v++, b += 3) {
let bone = skeletonBones[bones[v]];
let vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2];
wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;
wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight;
}
worldVertices[w] = wx;
worldVertices[w + 1] = wy;
}
} else {
let deform = deformArray;
for (let w = offset, b = skip * 3, f = skip << 1; w < count; w += stride) {
let wx = 0, wy = 0;
let n = bones[v++];
n += v;
for (; v < n; v++, b += 3, f += 2) {
let bone = skeletonBones[bones[v]];
let vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2];
wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;
wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight;
}
worldVertices[w] = wx;
worldVertices[w + 1] = wy;
}
}
}
/** Does not copy id (generated) or name (set on construction). **/
copyTo(attachment) {
if (this.bones) {
attachment.bones = new Array(this.bones.length);
Utils.arrayCopy(this.bones, 0, attachment.bones, 0, this.bones.length);
} else
attachment.bones = null;
if (this.vertices) {
attachment.vertices = Utils.newFloatArray(this.vertices.length);
Utils.arrayCopy(this.vertices, 0, attachment.vertices, 0, this.vertices.length);
}
attachment.worldVerticesLength = this.worldVerticesLength;
attachment.timelineAttachment = this.timelineAttachment;
}
};
// spine-core/src/attachments/Sequence.ts
var Sequence = class _Sequence {
static _nextID = 0;
id = _Sequence.nextID();
regions;
start = 0;
digits = 0;
/** The index of the region to show for the setup pose. */
setupIndex = 0;
constructor(count) {
this.regions = new Array(count);
}
copy() {
let copy = new _Sequence(this.regions.length);
Utils.arrayCopy(this.regions, 0, copy.regions, 0, this.regions.length);
copy.start = this.start;
copy.digits = this.digits;
copy.setupIndex = this.setupIndex;
return copy;
}
apply(slot, attachment) {
let index = slot.sequenceIndex;
if (index == -1) index = this.setupIndex;
if (index >= this.regions.length) index = this.regions.length - 1;
let region = this.regions[index];
if (attachment.region != region) {
attachment.region = region;
attachment.updateRegion();
}
}
getPath(basePath, index) {
let result = basePath;
let frame = (this.start + index).toString();
for (let i = this.digits - frame.length; i > 0; i--)
result += "0";
result += frame;
return result;
}
static nextID() {
return _Sequence._nextID++;
}
};
var SequenceMode = /* @__PURE__ */ ((SequenceMode2) => {
SequenceMode2[SequenceMode2["hold"] = 0] = "hold";
SequenceMode2[SequenceMode2["once"] = 1] = "once";
SequenceMode2[SequenceMode2["loop"] = 2] = "loop";
SequenceMode2[SequenceMode2["pingpong"] = 3] = "pingpong";
SequenceMode2[SequenceMode2["onceReverse"] = 4] = "onceReverse";
SequenceMode2[SequenceMode2["loopReverse"] = 5] = "loopReverse";
SequenceMode2[SequenceMode2["pingpongReverse"] = 6] = "pingpongReverse";
return SequenceMode2;
})(SequenceMode || {});
var SequenceModeValues = [
0 /* hold */,
1 /* once */,
2 /* loop */,
3 /* pingpong */,
4 /* onceReverse */,
5 /* loopReverse */,
6 /* pingpongReverse */
];
// spine-core/src/Animation.ts
var Animation = class {
/** The animation's name, which is unique across all animations in the skeleton. */
name;
timelines = [];
timelineIds = new StringSet();
/** The duration of the animation in seconds, which is the highest time of all keys in the timeline. */
duration;
constructor(name, timelines, duration) {
if (!name) throw new Error("name cannot be null.");
this.name = name;
this.setTimelines(timelines);
this.duration = duration;
}
setTimelines(timelines) {
if (!timelines) throw new Error("timelines cannot be null.");
this.timelines = timelines;
this.timelineIds.clear();
for (var i = 0; i < timelines.length; i++)
this.timelineIds.addAll(timelines[i].getPropertyIds());
}
hasTimeline(ids) {
for (let i = 0; i < ids.length; i++)
if (this.timelineIds.contains(ids[i])) return true;
return false;
}
/** Applies all the animation's timelines to the specified skeleton.
*
* See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, MixBlend, MixDirection)}.
* @param loop If true, the animation repeats after {@link #getDuration()}.
* @param events May be null to ignore fired events. */
apply(skeleton, lastTime, time, loop, events, alpha, blend, direction) {
if (!skeleton) throw new Error("skeleton cannot be null.");
if (loop && this.duration != 0) {
time %= this.duration;
if (lastTime > 0) lastTime %= this.duration;
}
let timelines = this.timelines;
for (let i = 0, n = timelines.length; i < n; i++)
timelines[i].apply(skeleton, lastTime, time, events, alpha, blend, direction);
}
};
var MixBlend = /* @__PURE__ */ ((MixBlend2) => {
MixBlend2[MixBlend2["setup"] = 0] = "setup";
MixBlend2[MixBlend2["first"] = 1] = "first";
MixBlend2[MixBlend2["replace"] = 2] = "replace";
MixBlend2[MixBlend2["add"] = 3] = "add";
return MixBlend2;
})(MixBlend || {});
var MixDirection = /* @__PURE__ */ ((MixDirection2) => {
MixDirection2[MixDirection2["mixIn"] = 0] = "mixIn";
MixDirection2[MixDirection2["mixOut"] = 1] = "mixOut";
return MixDirection2;
})(MixDirection || {});
var Property = {
rotate: 0,
x: 1,
y: 2,
scaleX: 3,
scaleY: 4,
shearX: 5,
shearY: 6,
inherit: 7,
rgb: 8,
alpha: 9,
rgb2: 10,
attachment: 11,
deform: 12,
event: 13,
drawOrder: 14,
ikConstraint: 15,
transformConstraint: 16,
pathConstraintPosition: 17,
pathConstraintSpacing: 18,
pathConstraintMix: 19,
physicsConstraintInertia: 20,
physicsConstraintStrength: 21,
physicsConstraintDamping: 22,
physicsConstraintMass: 23,
physicsConstraintWind: 24,
physicsConstraintGravity: 25,
physicsConstraintMix: 26,
physicsConstraintReset: 27,
sequence: 28
};
var Timeline = class {
propertyIds;
frames;
constructor(frameCount, propertyIds) {
this.propertyIds = propertyIds;
this.frames = Utils.newFloatArray(frameCount * this.getFrameEntries());
}
getPropertyIds() {
return this.propertyIds;
}
getFrameEntries() {
return 1;
}
getFrameCount() {
return this.frames.length / this.getFrameEntries();
}
getDuration() {
return this.frames[this.frames.length - this.getFrameEntries()];
}
static search1(frames, time) {
let n = frames.length;
for (let i = 1; i < n; i++)
if (frames[i] > time) return i - 1;
return n - 1;
}
static search(frames, time, step) {
let n = frames.length;
for (let i = step; i < n; i += step)
if (frames[i] > time) return i - step;
return n - step;
}
};
var CurveTimeline = class extends Timeline {
curves;
// type, x, y, ...
constructor(frameCount, bezierCount, propertyIds) {
super(frameCount, propertyIds);
this.curves = Utils.newFloatArray(
frameCount + bezierCount * 18
/*BEZIER_SIZE*/
);
this.curves[frameCount - 1] = 1;
}
/** Sets the specified key frame to linear interpolation. */
setLinear(frame) {
this.curves[frame] = 0;
}
/** Sets the specified key frame to stepped interpolation. */
setStepped(frame) {
this.curves[frame] = 1;
}
/** Shrinks the storage for Bezier curves, for use when <code>bezierCount</code> (specified in the constructor) was larger
* than the actual number of Bezier curves. */
shrink(bezierCount) {
let size = this.getFrameCount() + bezierCount * 18;
if (this.curves.length > size) {
let newCurves = Utils.newFloatArray(size);
Utils.arrayCopy(this.curves, 0, newCurves, 0, size);
this.curves = newCurves;
}
}
/** Stores the segments for the specified Bezier curve. For timelines that modify multiple values, there may be more than
* one curve per frame.
* @param bezier The ordinal of this Bezier curve for this timeline, between 0 and <code>bezierCount - 1</code> (specified
* in the constructor), inclusive.
* @param frame Between 0 and <code>frameCount - 1</code>, inclusive.
* @param value The index of the value for this frame that this curve is used for.
* @param time1 The time for the first key.
* @param value1 The value for the first key.
* @param cx1 The time for the first Bezier handle.
* @param cy1 The value for the first Bezier handle.
* @param cx2 The time of the second Bezier handle.
* @param cy2 The value for the second Bezier handle.
* @param time2 The time for the second key.
* @param value2 The value for the second key. */
setBezier(bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2) {
let curves = this.curves;
let i = this.getFrameCount() + bezier * 18;
if (value == 0) curves[frame] = 2 + i;
let tmpx = (time1 - cx1 * 2 + cx2) * 0.03, tmpy = (value1 - cy1 * 2 + cy2) * 0.03;
let dddx = ((cx1 - cx2) * 3 - time1 + time2) * 6e-3, dddy = ((cy1 - cy2) * 3 - value1 + value2) * 6e-3;
let ddx = tmpx * 2 + dddx, ddy = tmpy * 2 + dddy;
let dx = (cx1 - time1) * 0.3 + tmpx + dddx * 0.16666667, dy = (cy1 - value1) * 0.3 + tmpy + dddy * 0.16666667;
let x = time1 + dx, y = value1 + dy;
for (let n = i + 18; i < n; i += 2) {
curves[i] = x;
curves[i + 1] = y;
dx += ddx;
dy += ddy;
ddx += dddx;
ddy += dddy;
x += dx;
y += dy;
}
}
/** Returns the Bezier interpolated value for the specified time.
* @param frameIndex The index into {@link #getFrames()} for the values of the frame before <code>time</code>.
* @param valueOffset The offset from <code>frameIndex</code> to the value this curve is used for.
* @param i The index of the Bezier segments. See {@link #getCurveType(int)}. */
getBezierValue(time, frameIndex, valueOffset, i) {
let curves = this.curves;
if (curves[i] > time) {
let x2 = this.frames[frameIndex], y2 = this.frames[frameIndex + valueOffset];
return y2 + (time - x2) / (curves[i] - x2) * (curves[i + 1] - y2);
}
let n = i + 18;
for (i += 2; i < n; i += 2) {
if (curves[i] >= time) {
let x2 = curves[i - 2], y2 = curves[i - 1];
return y2 + (time - x2) / (curves[i] - x2) * (curves[i + 1] - y2);
}
}
frameIndex += this.getFrameEntries();
let x = curves[n - 2], y = curves[n - 1];
return y + (time - x) / (this.frames[frameIndex] - x) * (this.frames[frameIndex + valueOffset] - y);
}
};
var CurveTimeline1 = class extends CurveTimeline {
constructor(frameCount, bezierCount, propertyId) {
super(frameCount, bezierCount, [propertyId]);
}
getFrameEntries() {
return 2;
}
/** Sets the time and value for the specified frame.
* @param frame Between 0 and <code>frameCount</code>, inclusive.
* @param time The frame time in seconds. */
setFrame(frame, time, value) {
frame <<= 1;
this.frames[frame] = time;
this.frames[
frame + 1
/*VALUE*/
] = value;
}
/** Returns the interpolated value for the specified time. */
getCurveValue(time) {
let frames = this.frames;
let i = frames.length - 2;
for (let ii = 2; ii <= i; ii += 2) {
if (frames[ii] > time) {
i = ii - 2;
break;
}
}
let curveType = this.curves[i >> 1];
switch (curveType) {
case 0:
let before = frames[i], value = frames[
i + 1
/*VALUE*/
];
return value + (time - before) / (frames[
i + 2
/*ENTRIES*/
] - before) * (frames[
i + 2 + 1
/*VALUE*/
] - value);
case 1:
return frames[
i + 1
/*VALUE*/
];
}
return this.getBezierValue(
time,
i,
1,
curveType - 2
/*BEZIER*/
);
}
getRelativeValue(time, alpha, blend, current, setup) {
if (time < this.frames[0]) {
switch (blend) {
case 0 /* setup */:
return setup;
case 1 /* first */:
return current + (setup - current) * alpha;
}
return current;
}
let value = this.getCurveValue(time);
switch (blend) {
case 0 /* setup */:
return setup + value * alpha;
case 1 /* first */:
case 2 /* replace */:
value += setup - current;
}
return current + value * alpha;
}
getAbsoluteValue(time, alpha, blend, current, setup) {
if (time < this.frames[0]) {
switch (blend) {
case 0 /* setup */:
return setup;
case 1 /* first */:
return current + (setup - current) * alpha;
}
return current;
}
let value = this.getCurveValue(time);
if (blend == 0 /* setup */) return setup + (value - setup) * alpha;
return current + (value - current) * alpha;
}
getAbsoluteValue2(time, alpha, blend, current, setup, value) {
if (time < this.frames[0]) {
switch (blend) {
case 0 /* setup */:
return setup;
case 1 /* first */:
return current + (setup - current) * alpha;
}
return current;
}
if (blend == 0 /* setup */) return setup + (value - setup) * alpha;
return current + (value - current) * alpha;
}
getScaleValue(time, alpha, blend, direction, current, setup) {
const frames = this.frames;
if (time < frames[0]) {
switch (blend) {
case 0 /* setup */:
return setup;
case 1 /* first */:
return current + (setup - current) * alpha;
}
return current;
}
let value = this.getCurveValue(time) * setup;
if (alpha == 1) {
if (blend == 3 /* add */) return current + value - setup;
return value;
}
if (direction == 1 /* mixOut */) {
switch (blend) {
case 0 /* setup */:
return setup + (Math.abs(value) * MathUtils.signum(setup) - setup) * alpha;
case 1 /* first */:
case 2 /* replace */:
return current + (Math.abs(value) * MathUtils.signum(current) - current) * alpha;
}
} else {
let s = 0;
switch (blend) {
case 0 /* setup */:
s = Math.abs(setup) * MathUtils.signum(value);
return s + (value - s) * alpha;
case 1 /* first */:
case 2 /* replace */:
s = Math.abs(current) * MathUtils.signum(value);
return s + (value - s) * alpha;
}
}
return current + (value - setup) * alpha;
}
};
var CurveTimeline2 = class extends CurveTimeline {
/** @param bezierCount The maximum number of Bezier curves. See {@link #shrink(int)}.
* @param propertyIds Unique identifiers for the properties the timeline modifies. */
constructor(frameCount, bezierCount, propertyId1, propertyId2) {
super(frameCount, bezierCount, [propertyId1, propertyId2]);
}
getFrameEntries() {
return 3;
}
/** Sets the time and values for the specified frame.
* @param frame Between 0 and <code>frameCount</code>, inclusive.
* @param time The frame time in seconds. */
setFrame(frame, time, value1, value2) {
frame *= 3;
this.frames[frame] = time;
this.frames[
frame + 1
/*VALUE1*/
] = value1;
this.frames[
frame + 2
/*VALUE2*/
] = value2;
}
};
var RotateTimeline = class extends CurveTimeline1 {
boneIndex = 0;
constructor(frameCount, bezierCount, boneIndex) {
super(frameCount, bezierCount, Property.rotate + "|" + boneIndex);
this.boneIndex = boneIndex;
}
apply(skeleton, lastTime, time, events, alpha, blend, direction) {
let bone = skeleton.bones[this.boneIndex];
if (bone.active) bone.rotation = this.getRelativeValue(time, alpha, blend, bone.rotation, bone.data.rotation);
}
};
var TranslateTimeline = class extends CurveTimeline2 {
boneIndex = 0;
constructor(frameCount, bezierCount, boneIndex) {
super(
frameCount,
bezierCount,
Property.x + "|" + boneIndex,
Property.y + "|" + boneIndex
);
this.boneIndex = boneIndex;
}
apply(skeleton, lastTime, time, events, alpha, blend, direction) {
let bone = skeleton.bones[this.boneIndex];
if (!bone.active) return;
let frames = this.frames;
if (time < frames[0]) {
switch (blend) {
case 0 /* setup */:
bone.x = bone.data.x;
bone.y = bone.data.y;
return;
case 1 /* first */:
bone.x += (bone.data.x - bone.x) * alpha;
bone.y += (bone.data.y - bone.y) * alpha;
}
return;
}
let x = 0, y = 0;
let i = Timeline.search(
frames,
time,
3
/*ENTRIES*/
);
let curveType = this.curves[
i / 3
/*ENTRIES*/
];
switch (curveType) {
case 0:
let before = frames[i];
x = frames[
i + 1
/*VALUE1*/
];
y = frames[
i + 2
/*VALUE2*/
];
let t = (time - before) / (frames[
i + 3
/*ENTRIES*/
] - before);
x += (frames[
i + 3 + 1
/*VALUE1*/
] - x) * t;
y += (frames[
i + 3 + 2
/*VALUE2*/
] - y) * t;
break;
case 1:
x = frames[
i + 1
/*VALUE1*/
];
y = frames[
i + 2
/*VALUE2*/
];
break;
default:
x = this.getBezierValue(
time,
i,
1,
curveType - 2
/*BEZIER*/
);
y = this.getBezierValue(
time,
i,
2,
curveType + 18 - 2
/*BEZIER*/
);
}
switch (blend) {
case 0 /* setup */:
bone.x = bone.data.x + x * alpha;
bone.y = bone.data.y + y * alpha;
break;
case 1 /* first */:
case 2 /* replace */:
bone.x += (bone.data.x + x - bone.x) * alpha;
bone.y += (bone.data.y + y - bone.y) * alpha;
break;
case 3 /* add */:
bone.x += x * alpha;
bone.y += y * alpha;
}
}
};
var TranslateXTimeline = class extends CurveTimeline1 {
boneIndex = 0;
constructor(frameCount, bezierCount, boneIndex) {
super(frameCount, bezierCount, Property.x + "|" + boneIndex);
this.boneIndex = boneIndex;
}
apply(skeleton, lastTime, time, events, alpha, blend, direction) {
let bone = skeleton.bones[this.boneIndex];
if (bone.active) bone.x = this.getRelativeValue(time, alpha, blend, bone.x, bone.data.x);
}
};
var TranslateYTimeline = class extends CurveTimeline1 {
boneIndex = 0;
constructor(frameCount, bezierCount, boneIndex) {
super(frameCount, bezierCount, Property.y + "|" + boneIndex);
this.boneIndex = boneIndex;
}
apply(skeleton, lastTime, time, events, alpha, blend, direction) {
let bone = skeleton.bones[this.boneIndex];
if (bone.active) bone.y = this.getRelativeValue(time, alpha, blend, bone.y, bone.data.y);
}
};
var ScaleTimeline = class extends CurveTimeline2 {
boneIndex = 0;
constructor(frameCount, bezierCount, boneIndex) {
super(
frameCount,
bezierCount,
Property.scaleX + "|" + boneIndex,
Property.scaleY + "|" + boneIndex
);
this.boneIndex = boneIndex;
}
apply(skeleton, lastTime, time, events, alpha, blend, direction) {
let bone = skeleton.bones[this.boneIndex];
if (!bone.active) return;
let frames = this.frames;
if (time < frames[0]) {
switch (blend) {
case 0 /* setup */:
bone.scaleX = bone.data.scaleX;
bone.scaleY = bone.data.scaleY;
return;
case 1 /* first */:
bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha;
bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha;
}
return;
}
let x, y;
let i = Timeline.search(
frames,
time,
3
/*ENTRIES*/
);
let curveType = this.curves[
i / 3
/*ENTRIES*/
];
switch (curveType) {
case 0:
let before = frames[i];
x = frames[
i + 1
/*VALUE1*/
];
y = frames[
i + 2
/*VALUE2*/
];
let t = (time - before) / (frames[
i + 3
/*ENTRIES*/
] - before);
x += (frames[
i + 3 + 1
/*VALUE1*/
] - x) * t;
y += (frames[
i + 3 + 2
/*VALUE2*/
] - y) * t;
break;
case 1:
x = frames[
i + 1
/*VALUE1*/
];
y = frames[
i + 2
/*VALUE2*/
];
break;
default:
x = this.getBezierValue(
time,
i,
1,
curveType - 2
/*BEZIER*/
);
y = this.getBezierValue(
time,
i,
2,
curveType + 18 - 2
/*BEZIER*/
);
}
x *= bone.data.scaleX;
y *= bone.data.scaleY;
if (alpha == 1) {
if (blend == 3 /* add */) {
bone.scaleX += x - bone.data.scaleX;
bone.scaleY += y - bone.data.scaleY;
} else {
bone.scaleX = x;
bone.scaleY = y;
}
} else {
let bx = 0, by = 0;
if (direction == 1 /* mixOut */) {
switch (blend) {
case 0 /* setup */:
bx = bone.data.scaleX;
by = bone.data.scaleY;
bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha;
bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha;
break;
case 1 /* first */:
case 2 /* replace */:
bx = bone.scaleX;
by = bone.scaleY;
bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha;
bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha;
break;
case 3 /* add */:
bone.scaleX += (x - bone.data.scaleX) * alpha;
bone.scaleY += (y - bone.data.scaleY) * alpha;
}
} else {
switch (blend) {
case 0 /* setup */:
bx = Math.abs(bone.data.scaleX) * MathUtils.signum(x);
by = Math.abs(bone.data.scaleY) * MathUtils.signum(y);
bone.scaleX = bx + (x - bx) * alpha;
bone.scaleY = by + (y - by) * alpha;
break;
case 1 /* first */:
case 2 /* replace */:
bx = Math.abs(bone.scaleX) * MathUtils.signum(x);
by = Math.abs(bone.scaleY) * MathUtils.signum(y);
bone.scaleX = bx + (x - bx) * alpha;
bone.scaleY = by + (y - by) * alpha;
break;
case 3 /* add */:
bone.scaleX += (x - bone.data.scaleX) * alpha;
bone.scaleY += (y - bone.data.scaleY) * alpha;
}
}
}
}
};
var ScaleXTimeline = class extends CurveTimeline1 {
boneIndex = 0;
constructor(frameCount, bezierCount, boneIndex) {
super(frameCount, bezierCount, Property.scaleX + "|" + boneIndex);
this.boneIndex = boneIndex;
}
apply(skeleton, lastTime, time, events, alpha, blend, direction) {
let bone = skeleton.bones[this.boneIndex];
if (bone.active) bone.scaleX = this.getScaleValue(time, alpha, blend, direction, bone.scaleX, bone.data.scaleX);
}
};
var ScaleYTimeline = class extends CurveTimeline1 {
boneIndex = 0;
constructor(frameCount, bezierCount, boneIndex) {
super(frameCount, bezierCount, Property.scaleY + "|" + boneIndex);
this.boneIndex = boneIndex;
}
apply(skeleton, lastTime, time, events, alpha, blend, direction) {
let bone = skeleton.bones[this.boneIndex];
if (bone.active) bone.scaleY = this.getScaleValue(time, alpha, blend, direction, bone.scaleY, bone.data.scaleY);
}
};
var ShearTimeline = class extends CurveTimeline2 {
boneIndex = 0;
constructor(frameCount, bezierCount, boneIndex) {
super(
frameCount,
bezierCount,
Property.shearX + "|" + boneIndex,
Property.shearY + "|" + boneIndex
);
this.boneIndex = boneIndex;
}
apply(skeleton, lastTime, time, events, alpha, blend, direction) {
let bone = skeleton.bones[this.boneIndex];
if (!bone.active) return;
let frames = this.frames;
if (time < frames[0]) {
switch (blend) {
case 0 /* setup */:
bone.shearX = bone.data.shearX;
bone.shearY = bone.data.shearY;
return;
case 1 /* first */:
bone.shearX += (bone.data.shearX - bone.shearX) * alpha;
bone.shearY += (bone.data.shearY - bone.shearY) * alpha;
}
return;
}
let x = 0, y = 0;
let i = Timeline.search(
frames,
time,
3
/*ENTRIES*/
);
let curveType = this.curves[
i / 3
/*ENTRIES*/
];
switch (curveType) {
case 0:
let before = frames[i];
x = frames[
i + 1
/*VALUE1*/
];
y = frames[
i + 2
/*VALUE2*/
];
let t = (time - before) / (frames[
i + 3
/*ENTRIES*/
] - before);
x += (frames[
i + 3 + 1
/*VALUE1*/
] - x) * t;
y += (frames[
i + 3 + 2
/*VALUE2*/
] - y) * t;
break;
case 1:
x = frames[
i + 1
/*VALUE1*/
];
y = frames[
i + 2
/*VALUE2*/
];
break;
default:
x = this.getBezierValue(
time,
i,
1,
curveType - 2
/*BEZIER*/
);
y = this.getBezierValue(
time,
i,
2,
curveType + 18 - 2
/*BEZIER*/
);
}
switch (blend) {
case 0 /* setup */:
bone.shearX = bone.data.shearX + x * alpha;
bone.shearY = bone.data.shearY + y * alpha;
break;
case 1 /* first */:
case 2 /* replace */:
bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha;
bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha;
break;
case 3 /* add */:
bone.shearX += x * alpha;
bone.shearY += y * alpha;
}
}
};
var ShearXTimeline = class extends CurveTimeline1 {
boneIndex = 0;
constructor(frameCount, bezierCount, boneIndex) {
super(frameCount, bezierCount, Property.shearX + "|" + boneIndex);
this.boneIndex = boneIndex;
}
apply(skeleton, lastTime, time, events, alpha, blend, direction) {
let bone = skeleton.bones[this.boneIndex];
if (bone.active) bone.shearX = this.getRelativeValue(time, alpha, blend, bone.shearX, bone.data.shearX);
}
};
var ShearYTimeline = class extends CurveTimeline1 {
boneIndex = 0;
constructor(frameCount, bezierCount, boneIndex) {
super(frameCount, bezierCount, Property.shearY + "|" + boneIndex);
this.boneIndex = boneIndex;
}
apply(skeleton, lastTime, time, events, alpha, blend, direction) {
let bone = skeleton.bones[this.boneIndex];
if (bone.active) bone.shearY = this.getRelativeValue(time, alpha, blend, bone.shearY, bone.data.shearY);
}
};
var InheritTimeline = class extends Timeline {
boneIndex = 0;
constructor(frameCount, boneIndex) {
super(frameCount, [Property.inherit + "|" + boneIndex]);
this.boneIndex = boneIndex;
}
getFrameEntries() {
return 2;
}
/** Sets the transform mode for the specified frame.
* @param frame Between 0 and <code>frameCount</code>, inclusive.
* @param time The frame time in seconds. */
setFrame(frame, time, inherit) {
frame *= 2;
this.frames[frame] = time;
this.frames[
frame + 1
/*INHERIT*/
] = inherit;
}
apply(skeleton, lastTime, time, events, alpha, blend, direction) {
let bone = skeleton.bones[this.boneIndex];
if (!bone.active) return;
if (direction == 1 /* mixOut */) {
if (blend == 0 /* setup */) bone.inherit = bone.data.inherit;
return;
}
let frames = this.frames;
if (time < frames[0]) {
if (blend == 0 /* setup */ || blend == 1 /* first */) bone.inherit = bone.data.inherit;
return;
}
bone.inherit = this.frames[
Timeline.search(
frames,
time,
2
/*ENTRIES*/
) + 1
/*INHERIT*/
];
}
};
var RGBATimeline = class extends CurveTimeline {
slotIndex = 0;
constructor(frameCount, bezierCount, slotIndex) {
super(frameCount, bezierCount, [
Property.rgb + "|" + slotIndex,
Property.alpha + "|" + slotIndex
]);
this.slotIndex = slotIndex;
}
getFrameEntries() {
return 5;
}
/** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */
setFrame(frame, time, r, g, b, a) {
frame *= 5;
this.frames[frame] = time;
this.frames[
frame + 1
/*R*/
] = r;
this.frames[
frame + 2
/*G*/
] = g;
this.frames[
frame + 3
/*B*/
] = b;
this.frames[
frame + 4
/*A*/
] = a;
}
apply(skeleton, lastTime, time, events, alpha, blend, direction) {
let slot = skeleton.slots[this.slotIndex];
if (!slot.bone.active) return;
let frames = this.frames;
let color = slot.color;
if (time < frames[0]) {
let setup = slot.data.color;
switch (blend) {
case 0 /* setup */:
color.setFromColor(setup);
return;
case 1 /* first */:
color.add(
(setup.r - color.r) * alpha,
(setup.g - color.g) * alpha,
(setup.b - color.b) * alpha,
(setup.a - color.a) * alpha
);
}
return;
}
let r = 0, g = 0, b = 0, a = 0;
let i = Timeline.search(
frames,
time,
5
/*ENTRIES*/
);
let curveType = this.curves[
i / 5
/*ENTRIES*/
];
switch (curveType) {
case 0:
let before = frames[i];
r = frames[
i + 1
/*R*/
];
g = frames[
i + 2
/*G*/
];
b = frames[
i + 3
/*B*/
];
a = frames[
i + 4
/*A*/
];
let t = (time - before) / (frames[
i + 5
/*ENTRIES*/
] - before);
r += (frames[
i + 5 + 1
/*R*/
] - r) * t;
g += (frames[
i + 5 + 2
/*G*/
] - g) * t;
b += (frames[
i + 5 + 3
/*B*/
] - b) * t;
a += (frames[
i + 5 + 4
/*A*/
] - a) * t;
break;
case 1:
r = frames[
i + 1
/*R*/
];
g = frames[
i + 2
/*G*/
];
b = frames[
i + 3
/*B*/
];
a = frames[
i + 4
/*A*/
];
break;
default:
r = this.getBezierValue(
time,
i,
1,
curveType - 2
/*BEZIER*/
);
g = this.getBezierValue(
time,
i,
2,
curveType + 18 - 2
/*BEZIER*/
);
b = this.getBezierValue(
time,
i,
3,
curveType + 18 * 2 - 2
/*BEZIER*/
);
a = this.getBezierValue(
time,
i,
4,
curveType + 18 * 3 - 2
/*BEZIER*/
);
}
if (alpha == 1)
color.set(r, g, b, a);
else {
if (blend == 0 /* setup */) color.setFromColor(slot.data.color);
color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha);
}
}
};
var RGBTimeline = class extends CurveTimeline {
slotIndex = 0;
constructor(frameCount, bezierCount, slotIndex) {
super(frameCount, bezierCount, [
Property.rgb + "|" + slotIndex
]);
this.slotIndex = slotIndex;
}
getFrameEntries() {
return 4;
}
/** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */
setFrame(frame, time, r, g, b) {
frame <<= 2;
this.frames[frame] = time;
this.frames[
frame + 1
/*R*/
] = r;
this.frames[
frame + 2
/*G*/
] = g;
this.frames[
frame + 3
/*B*/
] = b;
}
apply(skeleton, lastTime, time, events, alpha, blend, direction) {
let slot = skeleton.slots[this.slotIndex];
if (!slot.bone.active) return;
let frames = this.frames;
let color = slot.color;
if (time < frames[0]) {
let setup = slot.data.color;
switch (blend) {
case 0 /* setup */:
color.r = setup.r;
color.g = setup.g;
color.b = setup.b;
return;
case 1 /* first */:
color.r += (setup.r - color.r) * alpha;
color.g += (setup.g - color.g) * alpha;
color.b += (setup.b - color.b) * alpha;
}
return;
}
let r = 0, g = 0, b = 0;
let i = Timeline.search(
frames,
time,
4
/*ENTRIES*/
);
let curveType = this.curves[i >> 2];
switch (curveType) {
case 0:
let before = frames[i];
r = frames[
i + 1
/*R*/
];
g = frames[
i + 2
/*G*/
];
b = frames[
i + 3
/*B*/
];
let t = (time - before) / (frames[
i + 4
/*ENTRIES*/
] - before);
r += (frames[
i + 4 + 1
/*R*/
] - r) * t;
g += (frames[
i + 4 + 2
/*G*/
] - g) * t;
b += (frames[
i + 4 + 3
/*B*/
] - b) * t;
break;
case 1:
r = frames[
i + 1
/*R*/
];
g = frames[
i + 2
/*G*/
];
b = frames[
i + 3
/*B*/
];
break;
default:
r = this.getBezierValue(
time,
i,
1,
curveType - 2
/*BEZIER*/
);
g = this.getBezierValue(
time,
i,
2,
curveType + 18 - 2
/*BEZIER*/
);
b = this.getBezierValue(
time,
i,
3,
curveType + 18 * 2 - 2
/*BEZIER*/
);
}
if (alpha == 1) {
color.r = r;
color.g = g;
color.b = b;
} else {
if (blend == 0 /* setup */) {
let setup = slot.data.color;
color.r = setup.r;
color.g = setup.g;
color.b = setup.b;
}
color.r += (r - color.r) * alpha;
color.g += (g - color.g) * alpha;
color.b += (b - color.b) * alpha;
}
}
};
var AlphaTimeline = class extends CurveTimeline1 {
slotIndex = 0;
constructor(frameCount, bezierCount, slotIndex) {
super(frameCount, bezierCount, Property.alpha + "|" + slotIndex);
this.slotIndex = slotIndex;
}
apply(skeleton, lastTime, time, events, alpha, blend, direction) {
let slot = skeleton.slots[this.slotIndex];
if (!slot.bone.active) return;
let color = slot.color;
if (time < this.frames[0]) {
let setup = slot.data.color;
switch (blend) {
case 0 /* setup */:
color.a = setup.a;
return;
case 1 /* first */:
color.a += (setup.a - color.a) * alpha;
}
return;
}
let a = this.getCurveValue(time);
if (alpha == 1)
color.a = a;
else {
if (blend == 0 /* setup */) color.a = slot.data.color.a;
color.a += (a - color.a) * alpha;
}
}
};
var RGBA2Timeline = class extends CurveTimeline {
slotIndex = 0;
constructor(frameCount, bezierCount, slotIndex) {
super(frameCount, bezierCount, [
Property.rgb + "|" + slotIndex,
Property.alpha + "|" + slotIndex,
Property.rgb2 + "|" + slotIndex
]);
this.slotIndex = slotIndex;
}
getFrameEntries() {
return 8;
}
/** Sets the time in seconds, light, and dark colors for the specified key frame. */
setFrame(frame, time, r, g, b, a, r2, g2, b2) {
frame <<= 3;
this.frames[frame] = time;
this.frames[
frame + 1
/*R*/
] = r;
this.frames[
frame + 2
/*G*/
] = g;
this.frames[
frame + 3
/*B*/
] = b;
this.frames[
frame + 4
/*A*/
] = a;
this.frames[
frame + 5
/*R2*/
] = r2;
this.frames[
frame + 6
/*G2*/
] = g2;
this.frames[
frame + 7
/*B2*/
] = b2;
}
apply(skeleton, lastTime, time, events, alpha, blend, direction) {
let slot = skeleton.slots[this.slotIndex];
if (!slot.bone.active) return;
let frames = this.frames;
let light = slot.color, dark = slot.darkColor;
if (time < frames[0]) {
let setupLight = slot.data.color, setupDark = slot.data.darkColor;
switch (blend) {
case 0 /* setup */:
light.setFromColor(setupLight);
dark