Pārlūkot izejas kodu

[ts] Port of commits c83a867, f4f22cd, 1a83e96 (inherit timeline and minor fixes).

Davide Tantillo 1 gadu atpakaļ
vecāks
revīzija
03d78d4381

+ 58 - 22
spine-ts/spine-core/src/Animation.ts

@@ -39,6 +39,7 @@ import { HasTextureRegion } from "./attachments/HasTextureRegion.js";
 import { SequenceMode, SequenceModeValues } from "./attachments/Sequence.js";
 import { PhysicsConstraint } from "./PhysicsConstraint.js";
 import { PhysicsConstraintData } from "./PhysicsConstraintData.js";
+import { Inherit } from "./BoneData.js";
 
 /** A simple container for a list of timelines and a name. */
 export class Animation {
@@ -134,34 +135,35 @@ const Property = {
 	scaleY: 4,
 	shearX: 5,
 	shearY: 6,
+	inherit: 7,
 
-	rgb: 7,
-	alpha: 8,
-	rgb2: 9,
+	rgb: 8,
+	alpha: 9,
+	rgb2: 10,
 
-	attachment: 10,
-	deform: 11,
+	attachment: 11,
+	deform: 12,
 
-	event: 12,
-	drawOrder: 13,
+	event: 13,
+	drawOrder: 14,
 
-	ikConstraint: 14,
-	transformConstraint: 15,
+	ikConstraint: 15,
+	transformConstraint: 16,
 
-	pathConstraintPosition: 16,
-	pathConstraintSpacing: 17,
-	pathConstraintMix: 18,
+	pathConstraintPosition: 17,
+	pathConstraintSpacing: 18,
+	pathConstraintMix: 19,
 
-	physicsConstraintInertia: 19,
-	physicsConstraintStrength: 20,
-	physicsConstraintDamping: 21,
-	physicsConstraintMass: 22,
-	physicsConstraintWind: 23,
-	physicsConstraintGravity: 24,
-	physicsConstraintMix: 25,
-	physicsConstraintReset: 26,
+	physicsConstraintInertia: 20,
+	physicsConstraintStrength: 21,
+	physicsConstraintDamping: 22,
+	physicsConstraintMass: 23,
+	physicsConstraintWind: 24,
+	physicsConstraintGravity: 25,
+	physicsConstraintMix: 26,
+	physicsConstraintReset: 27,
 
-	sequence: 27,
+	sequence: 28,
 }
 
 /** The interface for all timelines. */
@@ -804,7 +806,41 @@ export class ShearYTimeline extends CurveTimeline1 implements BoneTimeline {
 
 	apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
 		let bone = skeleton.bones[this.boneIndex];
-		if (bone.active) bone.shearY = this.getRelativeValue(time, alpha, blend, bone.shearX, bone.data.shearY);
+		if (bone.active) bone.shearY = this.getRelativeValue(time, alpha, blend, bone.shearY, bone.data.shearY);
+	}
+}
+
+export class InheritTimeline extends Timeline implements BoneTimeline {
+	boneIndex = 0;
+
+	constructor (frameCount: number, boneIndex: number) {
+		super(frameCount, [Property.inherit + "|" + boneIndex]);
+		this.boneIndex = boneIndex;
+	}
+
+	public getFrameEntries () {
+		return 2/*ENTRIES*/;
+	}
+
+	/** Sets the transform mode for the specified frame.
+	 * @param frame Between 0 and <code>frameCount</code>, inclusive.
+	 * @param time The frame time in seconds. */
+	public setFrame (frame: number, time: number, inherit: Inherit) {
+		frame *= 2/*ENTRIES*/;
+		this.frames[frame] = time;
+		this.frames[frame + 1/*INHERIT*/] = inherit;
+	}
+
+	public apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
+		let bone = skeleton.bones[this.boneIndex];
+		if (!bone.active) return;
+
+		let frames = this.frames;
+		if (time < frames[0]) {
+			if (blend == MixBlend.setup || blend == MixBlend.first) bone.inherit = bone.data.inherit;
+			return;
+		}
+		bone.inherit = this.frames[Timeline.search(frames, time, 2/*ENTRIES*/) + 1/*INHERIT*/];
 	}
 }
 

+ 17 - 14
spine-ts/spine-core/src/Bone.ts

@@ -27,7 +27,7 @@
  * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-import { BoneData, TransformMode } from "./BoneData.js";
+import { BoneData, Inherit } from "./BoneData.js";
 import { Physics, Skeleton } from "./Skeleton.js";
 import { Updatable } from "./Updatable.js";
 import { MathUtils, Vector2 } from "./Utils.js";
@@ -110,6 +110,8 @@ export class Bone implements Updatable {
 	/** The world Y position. If changed, {@link #updateAppliedTransform()} should be called. */
 	worldX = 0;
 
+	inherit: Inherit = Inherit.Normal;
+
 	sorted = false;
 	active = false;
 
@@ -174,8 +176,8 @@ export class Bone implements Updatable {
 		this.worldX = pa * x + pb * y + parent.worldX;
 		this.worldY = pc * x + pd * y + parent.worldY;
 
-		switch (this.data.transformMode) {
-			case TransformMode.Normal: {
+		switch (this.inherit) {
+			case Inherit.Normal: {
 				const rx = (rotation + shearX) * MathUtils.degRad;
 				const ry = (rotation + 90 + shearY) * MathUtils.degRad;
 				const la = Math.cos(rx) * scaleX;
@@ -188,7 +190,7 @@ export class Bone implements Updatable {
 				this.d = pc * lb + pd * ld;
 				return;
 			}
-			case TransformMode.OnlyTranslation: {
+			case Inherit.OnlyTranslation: {
 				const rx = (rotation + shearX) * MathUtils.degRad;
 				const ry = (rotation + 90 + shearY) * MathUtils.degRad;
 				this.a = Math.cos(rx) * scaleX;
@@ -197,7 +199,7 @@ export class Bone implements Updatable {
 				this.d = Math.sin(ry) * scaleY;
 				break;
 			}
-			case TransformMode.NoRotationOrReflection: {
+			case Inherit.NoRotationOrReflection: {
 				let s = pa * pa + pc * pc;
 				let prx = 0;
 				if (s > 0.0001) {
@@ -224,8 +226,8 @@ export class Bone implements Updatable {
 				this.d = pc * lb + pd * ld;
 				break;
 			}
-			case TransformMode.NoScale:
-			case TransformMode.NoScaleOrReflection: {
+			case Inherit.NoScale:
+			case Inherit.NoScaleOrReflection: {
 				rotation *= MathUtils.degRad;
 				const cos = Math.cos(rotation), sin = Math.sin(rotation);
 				let za = (pa * cos + pb * sin) / this.skeleton.scaleX;
@@ -235,7 +237,7 @@ export class Bone implements Updatable {
 				za *= s;
 				zc *= s;
 				s = Math.sqrt(za * za + zc * zc);
-				if (this.data.transformMode == TransformMode.NoScale
+				if (this.inherit == Inherit.NoScale
 					&& (pa * pd - pb * pc < 0) != (this.skeleton.scaleX < 0 != this.skeleton.scaleY < 0)) s = -s;
 				rotation = Math.PI / 2 + Math.atan2(zc, za);
 				const zb = Math.cos(rotation) * s;
@@ -269,6 +271,7 @@ export class Bone implements Updatable {
 		this.scaleY = data.scaleY;
 		this.shearX = data.shearX;
 		this.shearY = data.shearY;
+		this.inherit = data.inherit;
 	}
 
 	/** Computes the applied transform values from the world transform.
@@ -299,14 +302,14 @@ export class Bone implements Updatable {
 		this.ay = (dy * id - dx * ic);
 
 		let ra, rb, rc, rd;
-		if (this.data.transformMode == TransformMode.OnlyTranslation) {
+		if (this.inherit == Inherit.OnlyTranslation) {
 			ra = this.a;
 			rb = this.b;
 			rc = this.c;
 			rd = this.d;
 		} else {
-			switch (this.data.transformMode) {
-				case TransformMode.NoRotationOrReflection: {
+			switch (this.inherit) {
+				case Inherit.NoRotationOrReflection: {
 					let s = Math.abs(pa * pd - pb * pc) / (pa * pa + pc * pc);
 					let sa = pa / this.skeleton.scaleX;
 					let sc = pc / this.skeleton.scaleY;
@@ -317,8 +320,8 @@ export class Bone implements Updatable {
 					ib = pb * pid;
 					break;
 				}
-				case TransformMode.NoScale:
-				case TransformMode.NoScaleOrReflection:
+				case Inherit.NoScale:
+				case Inherit.NoScaleOrReflection:
 					let cos = MathUtils.cosDeg(this.rotation), sin = MathUtils.sinDeg(this.rotation);
 					pa = (pa * cos + pb * sin) / this.skeleton.scaleX;
 					pc = (pc * cos + pd * sin) / this.skeleton.scaleY;
@@ -327,7 +330,7 @@ export class Bone implements Updatable {
 					pa *= s;
 					pc *= s;
 					s = Math.sqrt(pa * pa + pc * pc);
-					if (this.data.transformMode == TransformMode.NoScale && pid < 0 != (this.skeleton.scaleX < 0 != this.skeleton.scaleY < 0)) s = -s;
+					if (this.inherit == Inherit.NoScale && pid < 0 != (this.skeleton.scaleX < 0 != this.skeleton.scaleY < 0)) s = -s;
 					let r = MathUtils.PI / 2 + Math.atan2(pc, pa);
 					pb = Math.cos(r) * s;
 					pd = Math.sin(r) * s;

+ 2 - 2
spine-ts/spine-core/src/BoneData.ts

@@ -65,7 +65,7 @@ export class BoneData {
 	shearY = 0;
 
 	/** The transform mode for how parent world transforms affect this bone. */
-	transformMode = TransformMode.Normal;
+	inherit = Inherit.Normal;
 
 	/** When true, {@link Skeleton#updateWorldTransform()} only updates this bone if the {@link Skeleton#skin} contains this
 	  * bone.
@@ -92,4 +92,4 @@ export class BoneData {
 }
 
 /** Determines how a bone inherits world transforms from parent bones. */
-export enum TransformMode { Normal, OnlyTranslation, NoRotationOrReflection, NoScale, NoScaleOrReflection }
+export enum Inherit { Normal, OnlyTranslation, NoRotationOrReflection, NoScale, NoScaleOrReflection }

+ 8 - 7
spine-ts/spine-core/src/IkConstraint.ts

@@ -28,7 +28,7 @@
  *****************************************************************************/
 
 import { Bone } from "./Bone.js";
-import { TransformMode } from "./BoneData.js";
+import { Inherit } from "./BoneData.js";
 import { IkConstraintData } from "./IkConstraintData.js";
 import { Physics, Skeleton } from "./Skeleton.js";
 import { Updatable } from "./Updatable.js";
@@ -120,12 +120,12 @@ export class IkConstraint implements Updatable {
 		let pa = p.a, pb = p.b, pc = p.c, pd = p.d;
 		let rotationIK = -bone.ashearX - bone.arotation, tx = 0, ty = 0;
 
-		switch (bone.data.transformMode) {
-			case TransformMode.OnlyTranslation:
+		switch (bone.inherit) {
+			case Inherit.OnlyTranslation:
 				tx = (targetX - bone.worldX) * MathUtils.signum(bone.skeleton.scaleX);
 				ty = (targetY - bone.worldY) * MathUtils.signum(bone.skeleton.scaleY);
 				break;
-			case TransformMode.NoRotationOrReflection:
+			case Inherit.NoRotationOrReflection:
 				let s = Math.abs(pa * pd - pb * pc) / Math.max(0.0001, pa * pa + pc * pc);
 				let sa = pa / bone.skeleton.scaleX;
 				let sc = pc / bone.skeleton.scaleY;
@@ -152,9 +152,9 @@ export class IkConstraint implements Updatable {
 			rotationIK += 360;
 		let sx = bone.ascaleX, sy = bone.ascaleY;
 		if (compress || stretch) {
-			switch (bone.data.transformMode) {
-				case TransformMode.NoScale:
-				case TransformMode.NoScaleOrReflection:
+			switch (bone.inherit) {
+				case Inherit.NoScale:
+				case Inherit.NoScaleOrReflection:
 					tx = targetX - bone.worldX;
 					ty = targetY - bone.worldY;
 			}
@@ -175,6 +175,7 @@ export class IkConstraint implements Updatable {
 	/** Applies 2 bone IK. The target is specified in the world coordinate system.
 	 * @param child A direct descendant of the parent bone. */
 	apply2 (parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, stretch: boolean, uniform: boolean, softness: number, alpha: number) {
+		if (parent.inherit != Inherit.Normal || child.inherit != Inherit.Normal) return;
 		let px = parent.ax, py = parent.ay, psx = parent.ascaleX, psy = parent.ascaleY, sx = psx, sy = psy, csx = child.ascaleX;
 		let os1 = 0, os2 = 0, s2 = 0;
 		if (psx < 0) {

+ 1 - 1
spine-ts/spine-core/src/Skeleton.ts

@@ -46,7 +46,7 @@ import { Color, Utils, MathUtils, Vector2, NumberArrayLike } from "./Utils.js";
  *
  * See [Instance objects](http://esotericsoftware.com/spine-runtime-architecture#Instance-objects) in the Spine Runtimes Guide. */
 export class Skeleton {
-	static yDown = false;;
+	static yDown = false;
 
 	/** The skeleton's setup pose data. */
 	data: SkeletonData;

+ 14 - 4
spine-ts/spine-core/src/SkeletonBinary.ts

@@ -27,7 +27,7 @@
  * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-import { Animation, Timeline, AttachmentTimeline, RGBATimeline, RGBTimeline, RGBA2Timeline, RGB2Timeline, AlphaTimeline, RotateTimeline, TranslateTimeline, TranslateXTimeline, TranslateYTimeline, ScaleTimeline, ScaleXTimeline, ScaleYTimeline, ShearTimeline, ShearXTimeline, ShearYTimeline, IkConstraintTimeline, TransformConstraintTimeline, PathConstraintPositionTimeline, PathConstraintSpacingTimeline, PathConstraintMixTimeline, DeformTimeline, DrawOrderTimeline, EventTimeline, CurveTimeline1, CurveTimeline2, CurveTimeline, SequenceTimeline, PhysicsConstraintResetTimeline, PhysicsConstraintInertiaTimeline, PhysicsConstraintStrengthTimeline, PhysicsConstraintDampingTimeline, PhysicsConstraintMassTimeline, PhysicsConstraintWindTimeline, PhysicsConstraintGravityTimeline, PhysicsConstraintMixTimeline } from "./Animation.js";
+import { Animation, Timeline, InheritTimeline, AttachmentTimeline, RGBATimeline, RGBTimeline, RGBA2Timeline, RGB2Timeline, AlphaTimeline, RotateTimeline, TranslateTimeline, TranslateXTimeline, TranslateYTimeline, ScaleTimeline, ScaleXTimeline, ScaleYTimeline, ShearTimeline, ShearXTimeline, ShearYTimeline, IkConstraintTimeline, TransformConstraintTimeline, PathConstraintPositionTimeline, PathConstraintSpacingTimeline, PathConstraintMixTimeline, DeformTimeline, DrawOrderTimeline, EventTimeline, CurveTimeline1, CurveTimeline2, CurveTimeline, SequenceTimeline, PhysicsConstraintResetTimeline, PhysicsConstraintInertiaTimeline, PhysicsConstraintStrengthTimeline, PhysicsConstraintDampingTimeline, PhysicsConstraintMassTimeline, PhysicsConstraintWindTimeline, PhysicsConstraintGravityTimeline, PhysicsConstraintMixTimeline } from "./Animation.js";
 import { VertexAttachment, Attachment } from "./attachments/Attachment.js";
 import { AttachmentLoader } from "./attachments/AttachmentLoader.js";
 import { HasTextureRegion } from "./attachments/HasTextureRegion.js";
@@ -113,7 +113,7 @@ export class SkeletonBinary {
 			data.shearX = input.readFloat();
 			data.shearY = input.readFloat();
 			data.length = input.readFloat() * scale;
-			data.transformMode = input.readInt(true);
+			data.inherit = input.readByte();
 			data.skinRequired = input.readBoolean();
 			if (nonessential) {
 				Color.rgba8888ToColor(data.color, input.readInt32());
@@ -248,7 +248,7 @@ export class SkeletonBinary {
 			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.step = 1 / input.readUnsignedByte();
 			data.inertia = input.readFloat();
 			data.strength = input.readFloat();
 			data.damping = input.readFloat();
@@ -802,7 +802,16 @@ export class SkeletonBinary {
 		for (let i = 0, n = input.readInt(true); i < n; i++) {
 			let boneIndex = input.readInt(true);
 			for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) {
-				let type = input.readByte(), frameCount = input.readInt(true), bezierCount = input.readInt(true);
+				let type = input.readByte(), frameCount = input.readInt(true);
+				if (type == BONE_INHERIT) {
+					let timeline = new InheritTimeline(frameCount, boneIndex);
+					for (let frame = 0; frame < frameCount; frame++) {
+						timeline.setFrame(frame, input.readFloat(), input.readByte());
+					}
+					timelines.push(timeline);
+					continue;
+				}
+				let bezierCount = input.readInt(true);
 				switch (type) {
 					case BONE_ROTATE:
 						timelines.push(readTimeline1(input, new RotateTimeline(frameCount, bezierCount, boneIndex), 1));
@@ -1286,6 +1295,7 @@ const BONE_SCALEY = 6;
 const BONE_SHEAR = 7;
 const BONE_SHEARX = 8;
 const BONE_SHEARY = 9;
+const BONE_INHERIT = 10;
 
 const SLOT_ATTACHMENT = 0;
 const SLOT_RGBA = 1;

+ 10 - 3
spine-ts/spine-core/src/SkeletonJson.ts

@@ -27,11 +27,11 @@
  * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-import { Animation, Timeline, AttachmentTimeline, RGBATimeline, RGBTimeline, AlphaTimeline, RGBA2Timeline, RGB2Timeline, RotateTimeline, TranslateTimeline, TranslateXTimeline, TranslateYTimeline, ScaleTimeline, ScaleXTimeline, ScaleYTimeline, ShearTimeline, ShearXTimeline, ShearYTimeline, IkConstraintTimeline, TransformConstraintTimeline, PathConstraintPositionTimeline, PathConstraintSpacingTimeline, PathConstraintMixTimeline, DeformTimeline, DrawOrderTimeline, EventTimeline, CurveTimeline1, CurveTimeline2, CurveTimeline, PhysicsConstraintResetTimeline, PhysicsConstraintInertiaTimeline, PhysicsConstraintStrengthTimeline, PhysicsConstraintDampingTimeline, PhysicsConstraintMassTimeline, PhysicsConstraintWindTimeline, PhysicsConstraintGravityTimeline, PhysicsConstraintMixTimeline } from "./Animation.js";
+import { Animation, Timeline, InheritTimeline, AttachmentTimeline, RGBATimeline, RGBTimeline, AlphaTimeline, RGBA2Timeline, RGB2Timeline, RotateTimeline, TranslateTimeline, TranslateXTimeline, TranslateYTimeline, ScaleTimeline, ScaleXTimeline, ScaleYTimeline, ShearTimeline, ShearXTimeline, ShearYTimeline, IkConstraintTimeline, TransformConstraintTimeline, PathConstraintPositionTimeline, PathConstraintSpacingTimeline, PathConstraintMixTimeline, DeformTimeline, DrawOrderTimeline, EventTimeline, CurveTimeline1, CurveTimeline2, CurveTimeline, PhysicsConstraintResetTimeline, PhysicsConstraintInertiaTimeline, PhysicsConstraintStrengthTimeline, PhysicsConstraintDampingTimeline, PhysicsConstraintMassTimeline, PhysicsConstraintWindTimeline, PhysicsConstraintGravityTimeline, PhysicsConstraintMixTimeline } from "./Animation.js";
 import { VertexAttachment, Attachment } from "./attachments/Attachment.js";
 import { AttachmentLoader } from "./attachments/AttachmentLoader.js";
 import { MeshAttachment } from "./attachments/MeshAttachment.js";
-import { BoneData, TransformMode } from "./BoneData.js";
+import { BoneData, Inherit } from "./BoneData.js";
 import { EventData } from "./EventData.js";
 import { Event } from "./Event.js";
 import { IkConstraintData } from "./IkConstraintData.js";
@@ -102,7 +102,7 @@ export class SkeletonJson {
 				data.scaleY = getValue(boneMap, "scaleY", 1);
 				data.shearX = getValue(boneMap, "shearX", 0);
 				data.shearY = getValue(boneMap, "shearY", 0);
-				data.transformMode = Utils.enumValue(TransformMode, getValue(boneMap, "transform", "Normal"));
+				data.inherit = Utils.enumValue(Inherit, getValue(boneMap, "inherit", "Normal"));
 				data.skinRequired = getValue(boneMap, "skin", false);
 
 				let color = getValue(boneMap, "color", null);
@@ -739,6 +739,13 @@ export class SkeletonJson {
 					} else if (timelineName === "sheary") {
 						let timeline = new ShearYTimeline(frames, frames, boneIndex);
 						timelines.push(readTimeline1(timelineMap, timeline, 0, 1));
+					} else if (timelineName === "inherit") {
+						let timeline = new InheritTimeline(frames, bone.index);
+						for (let frame = 0; frame < timelineMap.length; frame++) {
+							let aFrame = timelineMap[frame];
+							timeline.setFrame(frame, getValue(aFrame, "time", 0), Utils.enumValue(Inherit, getValue(aFrame, "inherit", "Normal")));
+						}
+						timelines.push(timeline);
 					}
 				}
 			}