mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-20 17:26:01 +08:00
[ts] Port latest physics changes.
This commit is contained in:
parent
86a320afc2
commit
be767b21ea
@ -47,7 +47,7 @@ export class IkConstraintData extends ConstraintData {
|
||||
}
|
||||
|
||||
/** Controls the bend direction of the IK bones, either 1 or -1. */
|
||||
bendDirection = 1;
|
||||
bendDirection = 0;
|
||||
|
||||
/** When true and only a single bone is being constrained, if the target is too close, the bone is scaled to reach it. */
|
||||
compress = false;
|
||||
@ -61,7 +61,7 @@ export class IkConstraintData extends ConstraintData {
|
||||
uniform = false;
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. */
|
||||
mix = 1;
|
||||
mix = 0;
|
||||
|
||||
/** For two bone IK, the distance from the maximum reach of the bones that rotation will slow. */
|
||||
softness = 0;
|
||||
|
||||
@ -134,7 +134,8 @@ export class PhysicsConstraint implements Updatable {
|
||||
this.reset();
|
||||
// Fall through.
|
||||
case Physics.update:
|
||||
this.remaining += Math.max(this.skeleton.time - this.lastTime, 0);
|
||||
const delta = Math.max(this.skeleton.time - this.lastTime, 0);
|
||||
this.remaining += delta;
|
||||
this.lastTime = this.skeleton.time;
|
||||
|
||||
const bx = bone.worldX, by = bone.worldY;
|
||||
@ -143,41 +144,52 @@ export class PhysicsConstraint implements Updatable {
|
||||
this.ux = bx;
|
||||
this.uy = by;
|
||||
} else {
|
||||
let remaining = this.remaining, i = this.inertia, step = this.data.step;
|
||||
let a = this.remaining, i = this.inertia, q = this.data.limit * delta, t = this.data.step, f = this.skeleton.data.referenceScale, d = -1;
|
||||
if (x || y) {
|
||||
if (x) {
|
||||
this.xOffset += (this.ux - bx) * i;
|
||||
const u = (this.ux - bx) * i;
|
||||
this.xOffset += u > q ? q : u < -q ? -q : u;
|
||||
this.ux = bx;
|
||||
}
|
||||
if (y) {
|
||||
this.yOffset += (this.uy - by) * i;
|
||||
const u = (this.uy - by) * i;
|
||||
this.yOffset += u > q ? q : u < -q ? -q : u;
|
||||
this.uy = by;
|
||||
}
|
||||
if (remaining >= step) {
|
||||
const m = this.massInverse * step, e = this.strength, w = this.wind * 100, g = this.gravity * -100;
|
||||
const d = Math.pow(this.damping, 60 * step);
|
||||
if (a >= t) {
|
||||
d = Math.pow(this.damping, 60 * t);
|
||||
const m = this.massInverse * t, e = this.strength, w = this.wind * f, g = this.gravity * f;
|
||||
do {
|
||||
if (x) {
|
||||
this.xVelocity += (w - this.xOffset * e) * m;
|
||||
this.xOffset += this.xVelocity * step;
|
||||
this.xOffset += this.xVelocity * t;
|
||||
this.xVelocity *= d;
|
||||
}
|
||||
if (y) {
|
||||
this.yVelocity += (g - this.yOffset * e) * m;
|
||||
this.yOffset += this.yVelocity * step;
|
||||
this.yVelocity -= (g + this.yOffset * e) * m;
|
||||
this.yOffset += this.yVelocity * t;
|
||||
this.yVelocity *= d;
|
||||
}
|
||||
remaining -= step;
|
||||
} while (remaining >= step);
|
||||
a -= t;
|
||||
} while (a >= t);
|
||||
}
|
||||
if (x) bone.worldX += this.xOffset * mix * this.data.x;
|
||||
if (y) bone.worldY += this.yOffset * mix * this.data.y;
|
||||
}
|
||||
if (rotateOrShearX || scaleX) {
|
||||
let ca = Math.atan2(bone.c, bone.a), c = 0, s = 0, mr = 0;
|
||||
let dx = this.cx - bone.worldX, dy = this.cy - bone.worldY;
|
||||
if (dx > q)
|
||||
dx = q;
|
||||
else if (dx < -q) //
|
||||
dx = -q;
|
||||
if (dy > q)
|
||||
dy = q;
|
||||
else if (dy < -q) //
|
||||
dy = -q;
|
||||
if (rotateOrShearX) {
|
||||
mr = (this.data.rotate + this.data.shearX) * mix;
|
||||
let dx = this.cx - bone.worldX, dy = this.cy - bone.worldY, r = Math.atan2(dy + this.ty, dx + this.tx) - ca - this.rotateOffset * mr;
|
||||
let r = Math.atan2(dy + this.ty, dx + this.tx) - ca - this.rotateOffset * mr;
|
||||
this.rotateOffset += (r - Math.ceil(r * MathUtils.invPI2 - 0.5) * MathUtils.PI2) * i;
|
||||
r = this.rotateOffset * mr + ca;
|
||||
c = Math.cos(r);
|
||||
@ -190,33 +202,33 @@ export class PhysicsConstraint implements Updatable {
|
||||
c = Math.cos(ca);
|
||||
s = Math.sin(ca);
|
||||
const r = l * bone.getWorldScaleX();
|
||||
if (r > 0) this.scaleOffset += ((this.cx - bone.worldX) * c + (this.cy - bone.worldY) * s) * i / r;
|
||||
if (r > 0) this.scaleOffset += (dx * c + dy * s) * i / r;
|
||||
}
|
||||
remaining = this.remaining;
|
||||
if (remaining >= step) {
|
||||
const m = this.massInverse * step, e = this.strength, w = this.wind, g = this.gravity;
|
||||
const d = Math.pow(this.damping, 60 * step);
|
||||
a = this.remaining;
|
||||
if (a >= t) {
|
||||
if (d == -1) d = Math.pow(this.damping, 60 * t);
|
||||
const m = this.massInverse * t, e = this.strength, w = this.wind, g = this.gravity, h = l / f;
|
||||
while (true) {
|
||||
remaining -= step;
|
||||
a -= t;
|
||||
if (scaleX) {
|
||||
this.scaleVelocity += (w * c - g * s - this.scaleOffset * e) * m;
|
||||
this.scaleOffset += this.scaleVelocity * step;
|
||||
this.scaleOffset += this.scaleVelocity * t;
|
||||
this.scaleVelocity *= d;
|
||||
}
|
||||
if (rotateOrShearX) {
|
||||
this.rotateVelocity += (-0.01 * l * (w * s + g * c) - this.rotateOffset * e) * m;
|
||||
this.rotateOffset += this.rotateVelocity * step;
|
||||
this.rotateVelocity -= ((w * s + g * c) * h + this.rotateOffset * e) * m;
|
||||
this.rotateOffset += this.rotateVelocity * t;
|
||||
this.rotateVelocity *= d;
|
||||
if (remaining < step) break;
|
||||
if (a < t) break;
|
||||
const r = this.rotateOffset * mr + ca;
|
||||
c = Math.cos(r);
|
||||
s = Math.sin(r);
|
||||
} else if (remaining < step) //
|
||||
} else if (a < t) //
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.remaining = remaining;
|
||||
this.remaining = a;
|
||||
}
|
||||
this.cx = bone.worldX;
|
||||
this.cy = bone.worldY;
|
||||
@ -268,6 +280,8 @@ export class PhysicsConstraint implements Updatable {
|
||||
bone.updateAppliedTransform();
|
||||
}
|
||||
|
||||
/** Translates the physics constraint so next {@link #update(Physics)} forces are applied as if the bone moved an additional
|
||||
* amount in world space. */
|
||||
translate (x: number, y: number) {
|
||||
this.ux -= x;
|
||||
this.uy -= y;
|
||||
@ -278,10 +292,7 @@ export class PhysicsConstraint implements Updatable {
|
||||
/** Rotates the physics constraint so next {@link #update(Physics)} forces are applied as if the bone rotated around the
|
||||
* specified point in world space. */
|
||||
rotate (x: number, y: number, degrees: number) {
|
||||
let r = degrees * MathUtils.degRad, cos = Math.cos(r), sin = Math.sin(r);
|
||||
r = this.tx * cos - this.ty * sin;
|
||||
this.ty = this.tx * sin + this.ty * cos;
|
||||
this.tx = r;
|
||||
const r = degrees * MathUtils.degRad, cos = Math.cos(r), sin = Math.sin(r);
|
||||
const dx = this.cx - x, dy = this.cy - y;
|
||||
this.translate(dx * cos - dy * sin - dx, dx * sin + dy * cos - dy);
|
||||
}
|
||||
|
||||
@ -48,6 +48,7 @@ export class PhysicsConstraintData extends ConstraintData {
|
||||
rotate = 0;
|
||||
scaleX = 0;
|
||||
shearX = 0;
|
||||
limit = 0;
|
||||
step = 0;
|
||||
inertia = 0;
|
||||
strength = 0;
|
||||
|
||||
@ -54,7 +54,7 @@ export class Skeleton {
|
||||
/** The skeleton's bones, sorted parent first. The root bone is always the first bone. */
|
||||
bones: Array<Bone>;
|
||||
|
||||
/** The skeleton's slots. */
|
||||
/** The skeleton's slots in the setup pose draw order. */
|
||||
slots: Array<Slot>;
|
||||
|
||||
/** The skeleton's slots in the order they should be drawn. The returned array may be modified to change the draw order. */
|
||||
|
||||
@ -80,11 +80,11 @@ export class SkeletonBinary {
|
||||
skeletonData.y = input.readFloat();
|
||||
skeletonData.width = input.readFloat();
|
||||
skeletonData.height = input.readFloat();
|
||||
skeletonData.referenceScale = input.readFloat() * scale;
|
||||
|
||||
let nonessential = input.readBoolean();
|
||||
if (nonessential) {
|
||||
skeletonData.fps = input.readFloat();
|
||||
|
||||
skeletonData.imagesPath = input.readString();
|
||||
skeletonData.audioPath = input.readString();
|
||||
}
|
||||
@ -128,6 +128,14 @@ export class SkeletonBinary {
|
||||
for (let i = 0; i < n; i++) {
|
||||
let slotName = input.readString();
|
||||
if (!slotName) throw new Error("Slot name must not be null.");
|
||||
let path: string | null = null;
|
||||
if (nonessential) {
|
||||
const slash = slotName!.lastIndexOf('/');
|
||||
if (slash != -1) {
|
||||
path = slotName.substring(0, slash);
|
||||
slotName = slotName.substring(slash + 1);
|
||||
}
|
||||
}
|
||||
let boneData = skeletonData.bones[input.readInt(true)];
|
||||
let data = new SlotData(i, slotName, boneData);
|
||||
Color.rgba8888ToColor(data.color, input.readInt32());
|
||||
@ -137,7 +145,10 @@ export class SkeletonBinary {
|
||||
|
||||
data.attachmentName = input.readStringRef();
|
||||
data.blendMode = input.readInt(true);
|
||||
if (nonessential) data.visible = input.readBoolean();
|
||||
if (nonessential) {
|
||||
data.visible = input.readBoolean();
|
||||
data.path = path;
|
||||
}
|
||||
skeletonData.slots.push(data);
|
||||
}
|
||||
|
||||
@ -152,14 +163,14 @@ export class SkeletonBinary {
|
||||
for (let ii = 0; ii < nn; ii++)
|
||||
data.bones.push(skeletonData.bones[input.readInt(true)]);
|
||||
data.target = skeletonData.bones[input.readInt(true)];
|
||||
data.mix = input.readFloat();
|
||||
data.softness = input.readFloat() * scale;
|
||||
let flags = input.readByte();
|
||||
data.skinRequired = (flags & 1) != 0;
|
||||
data.bendDirection = (flags & 2) != 0 ? 1 : -1;
|
||||
data.compress = (flags & 4) != 0;
|
||||
data.stretch = (flags & 8) != 0;
|
||||
data.uniform = (flags & 16) != 0;
|
||||
if ((flags & 32) != 0) data.mix = (flags & 64) != 0 ? input.readFloat() : 1;
|
||||
if ((flags & 128) != 0) data.softness = input.readFloat() * scale;
|
||||
skeletonData.ikConstraints.push(data);
|
||||
}
|
||||
|
||||
@ -174,22 +185,23 @@ export class SkeletonBinary {
|
||||
for (let ii = 0; ii < nn; ii++)
|
||||
data.bones.push(skeletonData.bones[input.readInt(true)]);
|
||||
data.target = skeletonData.bones[input.readInt(true)];
|
||||
const flags = input.readByte();
|
||||
let flags = input.readByte();
|
||||
data.skinRequired = (flags & 1) != 0;
|
||||
data.local = (flags & 2) != 0;
|
||||
data.relative = (flags & 4) != 0;
|
||||
data.offsetRotation = input.readFloat();
|
||||
data.offsetX = input.readFloat() * scale;
|
||||
data.offsetY = input.readFloat() * scale;
|
||||
data.offsetScaleX = input.readFloat();
|
||||
data.offsetScaleY = input.readFloat();
|
||||
data.offsetShearY = input.readFloat();
|
||||
data.mixRotate = input.readFloat();
|
||||
data.mixX = input.readFloat();
|
||||
data.mixY = input.readFloat();
|
||||
data.mixScaleX = input.readFloat();
|
||||
data.mixScaleY = input.readFloat();
|
||||
data.mixShearY = input.readFloat();
|
||||
if ((flags & 8) != 0) data.offsetRotation = input.readFloat();
|
||||
if ((flags & 16) != 0) data.offsetX = input.readFloat() * scale;
|
||||
if ((flags & 32) != 0) data.offsetY = input.readFloat() * scale;
|
||||
if ((flags & 64) != 0) data.offsetScaleX = input.readFloat();
|
||||
if ((flags & 128) != 0) data.offsetScaleY = input.readFloat();
|
||||
flags = input.readByte();
|
||||
if ((flags & 1) != 0) data.offsetShearY = input.readFloat();
|
||||
if ((flags & 2) != 0) data.mixRotate = input.readFloat();
|
||||
if ((flags & 4) != 0) data.mixX = input.readFloat();
|
||||
if ((flags & 8) != 0) data.mixY = input.readFloat();
|
||||
if ((flags & 16) != 0) data.mixScaleX = input.readFloat();
|
||||
if ((flags & 32) != 0) data.mixScaleY = input.readFloat();
|
||||
if ((flags & 64) != 0) data.mixShearY = input.readFloat();
|
||||
skeletonData.transformConstraints.push(data);
|
||||
}
|
||||
|
||||
@ -205,10 +217,11 @@ export class SkeletonBinary {
|
||||
for (let ii = 0; ii < nn; ii++)
|
||||
data.bones.push(skeletonData.bones[input.readInt(true)]);
|
||||
data.target = skeletonData.slots[input.readInt(true)];
|
||||
data.positionMode = input.readInt(true);
|
||||
data.spacingMode = input.readInt(true);
|
||||
data.rotateMode = input.readInt(true);
|
||||
data.offsetRotation = input.readFloat();
|
||||
const flags = input.readByte();
|
||||
data.positionMode = flags & 1;
|
||||
data.spacingMode = (flags >> 1) & 3;
|
||||
data.rotateMode = (flags >> 3) & 3;
|
||||
if ((flags & 128) != 0) data.offsetRotation = input.readFloat();
|
||||
data.position = input.readFloat();
|
||||
if (data.positionMode == PositionMode.Fixed) data.position *= scale;
|
||||
data.spacing = input.readFloat();
|
||||
@ -234,14 +247,14 @@ export class SkeletonBinary {
|
||||
if ((flags & 8) != 0) data.rotate = input.readFloat();
|
||||
if ((flags & 16) != 0) data.scaleX = input.readFloat();
|
||||
if ((flags & 32) != 0) data.shearX = input.readFloat();
|
||||
data.limit = ((flags & 64) != 0 ? input.readFloat() : 5000) * scale;
|
||||
data.step = 1 / input.readByte();
|
||||
data.inertia = input.readFloat();
|
||||
data.strength = input.readFloat();
|
||||
data.damping = input.readFloat();
|
||||
data.massInverse = input.readFloat();
|
||||
data.wind = input.readFloat() * scale;
|
||||
data.gravity = input.readFloat() * scale;
|
||||
data.mix = input.readFloat();
|
||||
data.massInverse = (flags & 128) != 0 ? input.readFloat() : 1;
|
||||
data.wind = input.readFloat();
|
||||
data.gravity = input.readFloat();
|
||||
flags = input.readByte();
|
||||
if ((flags & 1) != 0) data.inertiaGlobal = true;
|
||||
if ((flags & 2) != 0) data.strengthGlobal = true;
|
||||
@ -250,6 +263,7 @@ export class SkeletonBinary {
|
||||
if ((flags & 16) != 0) data.windGlobal = true;
|
||||
if ((flags & 32) != 0) data.gravityGlobal = true;
|
||||
if ((flags & 64) != 0) data.mixGlobal = true;
|
||||
data.mix = (flags & 128) != 0 ? input.readFloat() : 1;
|
||||
skeletonData.physicsConstraints.push(data);
|
||||
}
|
||||
|
||||
@ -365,7 +379,7 @@ export class SkeletonBinary {
|
||||
let path = (flags & 16) != 0 ? input.readStringRef() : null;
|
||||
const color = (flags & 32) != 0 ? input.readInt32() : 0xffffffff;
|
||||
const sequence = (flags & 64) != 0 ? this.readSequence(input) : null;
|
||||
let rotation = input.readFloat();
|
||||
let rotation = (flags & 128) != 0 ? input.readFloat() : 0;
|
||||
let x = input.readFloat();
|
||||
let y = input.readFloat();
|
||||
let scaleX = input.readFloat();
|
||||
@ -827,19 +841,20 @@ export class SkeletonBinary {
|
||||
for (let i = 0, n = input.readInt(true); i < n; i++) {
|
||||
let index = input.readInt(true), frameCount = input.readInt(true), frameLast = frameCount - 1;
|
||||
let timeline = new IkConstraintTimeline(frameCount, input.readInt(true), index);
|
||||
let time = input.readFloat(), mix = input.readFloat(), softness = input.readFloat() * scale;
|
||||
let flags = input.readByte();
|
||||
let time = input.readFloat(), mix = (flags & 1) != 0 ? ((flags & 2) != 0 ? input.readFloat() : 1) : 0;
|
||||
let softness = (flags & 4) != 0 ? input.readFloat() * scale : 0;
|
||||
for (let frame = 0, bezier = 0; ; frame++) {
|
||||
const flags = input.readByte();
|
||||
timeline.setFrame(frame, time, mix, softness, input.readByte(), (flags & 1) != 0, (flags & 2) != 0);
|
||||
timeline.setFrame(frame, time, mix, softness, (flags & 8) != 0 ? 1 : -1, (flags & 16) != 0, (flags & 32) != 0);
|
||||
if (frame == frameLast) break;
|
||||
let time2 = input.readFloat(), mix2 = input.readFloat(), softness2 = input.readFloat() * scale;
|
||||
switch (input.readByte()) {
|
||||
case CURVE_STEPPED:
|
||||
timeline.setStepped(frame);
|
||||
break;
|
||||
case CURVE_BEZIER:
|
||||
setBezier(input, timeline, bezier++, frame, 0, time, time2, mix, mix2, 1);
|
||||
setBezier(input, timeline, bezier++, frame, 1, time, time2, softness, softness2, scale);
|
||||
flags = input.readByte();
|
||||
const time2 = input.readFloat(), mix2 = (flags & 1) != 0 ? ((flags & 2) != 0 ? input.readFloat() : 1) : 0;
|
||||
const softness2 = (flags & 4) != 0 ? input.readFloat() * scale : 0;
|
||||
if ((flags & 64) != 0) {
|
||||
timeline.setStepped(frame);
|
||||
} else if ((flags & 128) != 0) {
|
||||
setBezier(input, timeline, bezier++, frame, 0, time, time2, mix, mix2, 1);
|
||||
setBezier(input, timeline, bezier++, frame, 1, time, time2, softness, softness2, scale);
|
||||
}
|
||||
time = time2;
|
||||
mix = mix2;
|
||||
@ -953,10 +968,10 @@ export class SkeletonBinary {
|
||||
timelines.push(readTimeline1(input, new PhysicsConstraintMassTimeline(frameCount, bezierCount, index), 1));
|
||||
break;
|
||||
case PHYSICS_WIND:
|
||||
timelines.push(readTimeline1(input, new PhysicsConstraintWindTimeline(frameCount, bezierCount, index), scale));
|
||||
timelines.push(readTimeline1(input, new PhysicsConstraintWindTimeline(frameCount, bezierCount, index), 1));
|
||||
break;
|
||||
case PHYSICS_GRAVITY:
|
||||
timelines.push(readTimeline1(input, new PhysicsConstraintGravityTimeline(frameCount, bezierCount, index), scale));
|
||||
timelines.push(readTimeline1(input, new PhysicsConstraintGravityTimeline(frameCount, bezierCount, index), 1));
|
||||
break;
|
||||
case PHYSICS_MIX:
|
||||
timelines.push(readTimeline1(input, new PhysicsConstraintMixTimeline(frameCount, bezierCount, index), 1));
|
||||
|
||||
@ -49,8 +49,9 @@ export class SkeletonData {
|
||||
/** The skeleton's bones, sorted parent first. The root bone is always the first bone. */
|
||||
bones = new Array<BoneData>(); // Ordered parents first.
|
||||
|
||||
/** The skeleton's slots. */
|
||||
/** The skeleton's slots in the setup pose draw order. */
|
||||
slots = new Array<SlotData>(); // Setup pose draw order.
|
||||
|
||||
skins = new Array<Skin>();
|
||||
|
||||
/** The skeleton's default skin. By default this skin contains all attachments that were not in a skin in Spine.
|
||||
@ -89,6 +90,10 @@ export class SkeletonData {
|
||||
/** The height of the skeleton's axis aligned bounding box in the setup pose. */
|
||||
height: number = 0;
|
||||
|
||||
/** Baseline scale factor for applying distance-dependent effects on non-scalable properties, such as angle or scale. Default
|
||||
* is 100. */
|
||||
referenceScale = 100;
|
||||
|
||||
/** The Spine version used to export the skeleton data, or null. */
|
||||
version: string | null = null;
|
||||
|
||||
|
||||
@ -79,8 +79,10 @@ export class SkeletonJson {
|
||||
skeletonData.y = skeletonMap.y;
|
||||
skeletonData.width = skeletonMap.width;
|
||||
skeletonData.height = skeletonMap.height;
|
||||
skeletonData.referenceScale = getValue(skeletonMap, "referenceScale", 100) * scale;
|
||||
skeletonData.fps = skeletonMap.fps;
|
||||
skeletonData.imagesPath = skeletonMap.images;
|
||||
skeletonData.imagesPath = skeletonMap.images ?? null;
|
||||
skeletonData.audioPath = skeletonMap.audio ?? null;
|
||||
}
|
||||
|
||||
// Bones
|
||||
@ -114,9 +116,16 @@ export class SkeletonJson {
|
||||
if (root.slots) {
|
||||
for (let i = 0; i < root.slots.length; i++) {
|
||||
let slotMap = root.slots[i];
|
||||
let path: string | null = null;
|
||||
let slotName = slotMap.name;
|
||||
const slash = slotName.lastIndexOf('/');
|
||||
if (slash != -1) {
|
||||
path = slotName.substring(0, slash);
|
||||
slotName = slotName.substring(slash + 1);
|
||||
}
|
||||
let boneData = skeletonData.findBone(slotMap.bone);
|
||||
if (!boneData) throw new Error(`Couldn't find bone ${slotMap.bone} for slot ${slotMap.name}`);
|
||||
let data = new SlotData(skeletonData.slots.length, slotMap.name, boneData);
|
||||
if (!boneData) throw new Error(`Couldn't find bone ${slotMap.bone} for slot ${slotName}`);
|
||||
let data = new SlotData(skeletonData.slots.length, slotName, boneData);
|
||||
|
||||
let color: string = getValue(slotMap, "color", null);
|
||||
if (color) data.color.setFromString(color);
|
||||
@ -126,6 +135,8 @@ export class SkeletonJson {
|
||||
|
||||
data.attachmentName = getValue(slotMap, "attachment", null);
|
||||
data.blendMode = Utils.enumValue(BlendMode, getValue(slotMap, "blend", "normal"));
|
||||
data.visible = getValue(slotMap, "visible", true);
|
||||
data.path = path;
|
||||
skeletonData.slots.push(data);
|
||||
}
|
||||
}
|
||||
@ -253,13 +264,14 @@ export class SkeletonJson {
|
||||
data.rotate = getValue(constraintMap, "rotate", 0);
|
||||
data.scaleX = getValue(constraintMap, "scaleX", 0);
|
||||
data.shearX = getValue(constraintMap, "shearX", 0);
|
||||
data.limit = getValue(constraintMap, "limit", 5000) * scale;
|
||||
data.step = 1 / getValue(constraintMap, "fps", 60);
|
||||
data.inertia = getValue(constraintMap, "inertia", 1);
|
||||
data.strength = getValue(constraintMap, "strength", 100);
|
||||
data.damping = getValue(constraintMap, "damping", 1);
|
||||
data.massInverse = 1 / getValue(constraintMap, "mass", 1);
|
||||
data.wind = getValue(constraintMap, "wind", 0) * scale;
|
||||
data.gravity = getValue(constraintMap, "gravity", 0) * scale;
|
||||
data.wind = getValue(constraintMap, "wind", 0);
|
||||
data.gravity = getValue(constraintMap, "gravity", 0);
|
||||
data.mix = getValue(constraintMap, "mix", 1);
|
||||
data.inertiaGlobal = getValue(constraintMap, "inertiaGlobal", false);
|
||||
data.strengthGlobal = getValue(constraintMap, "strengthGlobal", false);
|
||||
@ -911,7 +923,6 @@ export class SkeletonJson {
|
||||
}
|
||||
|
||||
let timeline;
|
||||
let timelineScale = 1;
|
||||
if (timelineName == "inertia")
|
||||
timeline = new PhysicsConstraintInertiaTimeline(frames, frames, constraintIndex);
|
||||
else if (timelineName == "strength")
|
||||
@ -920,19 +931,15 @@ export class SkeletonJson {
|
||||
timeline = new PhysicsConstraintDampingTimeline(frames, frames, constraintIndex);
|
||||
else if (timelineName == "mass")
|
||||
timeline = new PhysicsConstraintMassTimeline(frames, frames, constraintIndex);
|
||||
else if (timelineName == "wind") {
|
||||
else if (timelineName == "wind")
|
||||
timeline = new PhysicsConstraintWindTimeline(frames, frames, constraintIndex);
|
||||
timelineScale = scale;
|
||||
}
|
||||
else if (timelineName == "gravity") {
|
||||
else if (timelineName == "gravity")
|
||||
timeline = new PhysicsConstraintGravityTimeline(frames, frames, constraintIndex);
|
||||
timelineScale = scale;
|
||||
}
|
||||
else if (timelineName == "mix") //
|
||||
timeline = new PhysicsConstraintMixTimeline(frames, frames, constraintIndex);
|
||||
else
|
||||
continue;
|
||||
timelines.push(readTimeline1(timelineMap, timeline, 0, timelineScale));
|
||||
timelines.push(readTimeline1(timelineMap, timeline, 0, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,6 +58,10 @@ export class SlotData {
|
||||
/** False if the slot was hidden in Spine and nonessential data was exported. Does not affect runtime rendering. */
|
||||
visible = true;
|
||||
|
||||
/** The folders for this slot in the draw order, delimited by <code>/</code>, or null if nonessential data was not exported. */
|
||||
path: string | null = null;
|
||||
|
||||
|
||||
constructor (index: number, name: string, boneData: BoneData) {
|
||||
if (index < 0) throw new Error("index must be >= 0.");
|
||||
if (!name) throw new Error("name cannot be null.");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user