Parcourir la source

[ts][pixi-v8] Moved state.apply and UWT right after time updates. (#2679)

Davide il y a 10 mois
Parent
commit
8a8fc74f8e

+ 3 - 3
spine-ts/spine-pixi-v8/example/control-bones-example.html

@@ -53,12 +53,12 @@
         // from one animation to the next.
         stretchyman.state.data.defaultMix = 0.2;
 
+        // Set animation "run" on track 0, looped.
+        stretchyman.state.setAnimation(0, "idle", true);
+
         // Center the spine object on screen.
         stretchyman.x = window.innerWidth / 2;
         stretchyman.y = window.innerHeight / 2 + stretchyman.getBounds().height / 2;
-
-        // Set animation "run" on track 0, looped.
-        stretchyman.state.setAnimation(0, "idle", true);
         app.stage.addChild(stretchyman);
 
         const controlBoneNames = [

+ 3 - 3
spine-ts/spine-pixi-v8/example/index.html

@@ -36,13 +36,13 @@
         // from one animation to the next.
         spineboy.state.data.defaultMix = 0.2;
 
+        // Set animation "run" on track 0, looped.
+        spineboy.state.setAnimation(0, "run", true);
+
         // Center the spine object on screen.
         spineboy.x = window.innerWidth / 2;
         spineboy.y = window.innerHeight / 2 + spineboy.getBounds().height / 2;
 
-        // Set animation "run" on track 0, looped.
-        spineboy.state.setAnimation(0, "run", true);
-
         // Add the display object to the stage.
         app.stage.addChild(spineboy);
       })();

+ 3 - 3
spine-ts/spine-pixi-v8/example/manual-loading.html

@@ -43,13 +43,13 @@
         // from one animation to the next.
         spineboy.state.data.defaultMix = 0.2;
 
+        // Set animation "run" on track 0, looped.
+        spineboy.state.setAnimation(0, "run", true);
+
         // Center the spine object on screen.
         spineboy.x = window.innerWidth / 2;
         spineboy.y = window.innerHeight / 2 + spineboy.getBounds().height / 2;
 
-        // Set animation "run" on track 0, looped.
-        spineboy.state.setAnimation(0, "run", true);
-
         // Add the display object to the stage.
         app.stage.addChild(spineboy);
       })();

+ 4 - 4
spine-ts/spine-pixi-v8/example/mouse-following.html

@@ -36,14 +36,14 @@
                 // from one animation to another.
                 spineboy.state.data.defaultMix = 0.2;
 
-                // Center the Spine object on screen.
-                spineboy.x = window.innerWidth / 2;
-                spineboy.y = window.innerHeight / 2 + spineboy.getBounds().height / 2;
-
                 // Set looping animations "idle" on track 0 and "aim" on track 1.
                 spineboy.state.setAnimation(0, "idle", true);
                 spineboy.state.setAnimation(1, "aim", true);
 
+                // Center the Spine object on screen.
+                spineboy.x = window.innerWidth / 2;
+                spineboy.y = window.innerHeight / 2 + spineboy.getBounds().height / 2;
+
                 // Add the display object to the stage.
                 app.stage.addChild(spineboy);
                 app.stage.hitArea = new PIXI.Rectangle(0, 0, app.view.width, app.view.height);

+ 4 - 3
spine-ts/spine-pixi-v8/example/slot-objects.html

@@ -35,13 +35,13 @@
         // from one animation to the next.
         spineboy.state.data.defaultMix = 0.2;
 
+        // Set animation "run" on track 0, looped.
+        spineboy.state.setAnimation(0, "walk", true);
+
         // Center the spine object on screen.
         spineboy.x = window.innerWidth / 2;
         spineboy.y = window.innerHeight / 2 + spineboy.getBounds().height / 2;
 
-        // Set animation "run" on track 0, looped.
-        spineboy.state.setAnimation(0, "walk", true);
-
         // Add the display object to the stage.
         app.stage.addChild(spineboy);
 
@@ -126,6 +126,7 @@
         // for clipping attachments having slot objects
         setTimeout(() => {
           spineboy.state.setAnimation(0, "portal", true)
+          spineboy.update(0)
           const tooth3 = PIXI.Sprite.from('raptor_jaw');
           tooth3.scale.set(2);
           tooth3.x = -60;

+ 23 - 23
spine-ts/spine-pixi-v8/src/Spine.ts

@@ -232,6 +232,7 @@ export class Spine extends ViewContainer {
 		this._autoUpdate = value;
 	}
 
+	private hasNeverUpdated = true;
 	constructor (options: SpineOptions | SkeletonData) {
 		if (options instanceof SkeletonData) {
 			options = {
@@ -257,8 +258,6 @@ export class Spine extends ViewContainer {
 		for (let i = 0; i < slots.length; i++) {
 			this.attachmentCacheData[i] = Object.create(null);
 		}
-
-		this._updateState(0);
 	}
 
 	/** If {@link Spine.autoUpdate} is `false`, this method allows to update the AnimationState and the Skeleton with the given delta. */
@@ -274,7 +273,7 @@ export class Spine extends ViewContainer {
 	protected internalUpdate (_deltaFrame: any, deltaSeconds?: number): void {
 		// Because reasons, pixi uses deltaFrames at 60fps.
 		// We ignore the default deltaFrames and use the deltaSeconds from pixi ticker.
-		this._updateState(deltaSeconds ?? Ticker.shared.deltaMS / 1000);
+		this._updateAndApplyState(deltaSeconds ?? Ticker.shared.deltaMS / 1000);
 	}
 
 	get bounds () {
@@ -343,16 +342,27 @@ export class Spine extends ViewContainer {
 	}
 
 	/**
-	 * Will update the state based on the specified time, this will not apply the state to the skeleton
-	 * as this is differed until the `applyState` method is called.
+	 * Advance the state and skeleton by the given time, then update slot objects too.
+	 * The container transform is not updated.
 	 *
 	 * @param time the time at which to set the state
-	 * @internal
 	 */
-	_updateState (time: number) {
+	private _updateAndApplyState (time: number) {
+		this.hasNeverUpdated = false;
+
 		this.state.update(time);
 		this.skeleton.update(time);
 
+		const { skeleton } = this;
+
+		this.state.apply(skeleton);
+
+		this.beforeUpdateWorldTransforms(this);
+		skeleton.updateWorldTransform(Physics.update);
+		this.afterUpdateWorldTransforms(this);
+
+		this.updateSlotObjects();
+
 		this._stateChanged = true;
 
 		this._boundsDirty = true;
@@ -361,31 +371,17 @@ export class Spine extends ViewContainer {
 	}
 
 	/**
-	 * Applies the state to this spine instance.
-	 * - updates the state to the skeleton
-	 * - updates its world transform (spine world transform)
 	 * - validates the attachments - to flag if the attachments have changed this state
 	 * - transforms the attachments - to update the vertices of the attachments based on the new positions
-	 * - update the slot attachments - to update the position, rotation, scale, and visibility of the attached containers
 	 * @internal
 	 */
-	_applyState () {
+	_validateAndTransformAttachments () {
 		if (!this._stateChanged) return;
 		this._stateChanged = false;
 
-		const { skeleton } = this;
-
-		this.state.apply(skeleton);
-
-		this.beforeUpdateWorldTransforms(this);
-		skeleton.updateWorldTransform(Physics.update);
-		this.afterUpdateWorldTransforms(this);
-
 		this.validateAttachments();
 
 		this.transformAttachments();
-
-		this.updateSlotObjects();
 	}
 
 	private validateAttachments () {
@@ -802,7 +798,11 @@ export class Spine extends ViewContainer {
 		skeletonBounds.update(this.skeleton, true);
 
 		if (skeletonBounds.minX === Infinity) {
-			this._applyState();
+			if (this.hasNeverUpdated) {
+				this._updateAndApplyState(0);
+				this._boundsDirty = false;
+			}
+			this._validateAndTransformAttachments();
 
 			const drawOrder = this.skeleton.drawOrder;
 			const bounds = this._bounds;

+ 3 - 3
spine-ts/spine-pixi-v8/src/SpinePipe.ts

@@ -66,7 +66,7 @@ export class SpinePipe implements RenderPipe<Spine> {
 	}
 
 	validateRenderable (spine: Spine): boolean {
-		spine._applyState();
+		spine._validateAndTransformAttachments();
 
 		// if pine attachments have changed, we need to rebuild the batch!
 		if (spine.spineAttachmentsDirty) {
@@ -109,7 +109,7 @@ export class SpinePipe implements RenderPipe<Spine> {
 
 		const roundPixels = (this.renderer._roundPixels | spine._roundPixels) as 0 | 1;
 
-		spine._applyState();
+		spine._validateAndTransformAttachments();
 
 		for (let i = 0, n = drawOrder.length; i < n; i++) {
 			const slot = drawOrder[i];
@@ -148,7 +148,7 @@ export class SpinePipe implements RenderPipe<Spine> {
 		// we assume that spine will always change its verts size..
 		const gpuSpine = this.gpuSpineData[spine.uid];
 
-		spine._applyState();
+		spine._validateAndTransformAttachments();
 
 		const drawOrder = spine.skeleton.drawOrder;