diff --git a/src/core/display/Transform.js b/src/core/display/Transform.js index 718d791..183fa0b 100644 --- a/src/core/display/Transform.js +++ b/src/core/display/Transform.js @@ -67,10 +67,10 @@ */ updateSkew() { - this._cx = Math.cos(this.rotation - this.skew._y); - this._sx = Math.sin(this.rotation - this.skew._y); - this._cy = Math.cos(this.rotation + (Math.PI / 2) + this.skew._x); - this._sy = Math.sin(this.rotation + (Math.PI / 2) + this.skew._x); + this._cx = Math.cos(this.rotation + this.skew._y); + this._sx = Math.sin(this.rotation + this.skew._y); + this._cy = -Math.sin(this.rotation - this.skew._x); // cos, added PI/2 + this._sy = Math.cos(this.rotation - this.skew._x); // sin, added PI/2 } /** diff --git a/src/core/display/Transform.js b/src/core/display/Transform.js index 718d791..183fa0b 100644 --- a/src/core/display/Transform.js +++ b/src/core/display/Transform.js @@ -67,10 +67,10 @@ */ updateSkew() { - this._cx = Math.cos(this.rotation - this.skew._y); - this._sx = Math.sin(this.rotation - this.skew._y); - this._cy = Math.cos(this.rotation + (Math.PI / 2) + this.skew._x); - this._sy = Math.sin(this.rotation + (Math.PI / 2) + this.skew._x); + this._cx = Math.cos(this.rotation + this.skew._y); + this._sx = Math.sin(this.rotation + this.skew._y); + this._cy = -Math.sin(this.rotation - this.skew._x); // cos, added PI/2 + this._sy = Math.cos(this.rotation - this.skew._x); // sin, added PI/2 } /** diff --git a/src/core/display/TransformStatic.js b/src/core/display/TransformStatic.js index 521f1f2..e763127 100644 --- a/src/core/display/TransformStatic.js +++ b/src/core/display/TransformStatic.js @@ -75,8 +75,8 @@ { this._cx = Math.cos(this.rotation + this.skew._y); this._sx = Math.sin(this.rotation + this.skew._y); - this._cy = Math.cos(this.rotation + (Math.PI / 2) - this.skew._x); - this._sy = Math.sin(this.rotation + (Math.PI / 2) - this.skew._x); + this._cy = -Math.sin(this.rotation - this.skew._x); // cos, added PI/2 + this._sy = Math.cos(this.rotation - this.skew._x); // sin, added PI/2 this._localID ++; } diff --git a/src/core/display/Transform.js b/src/core/display/Transform.js index 718d791..183fa0b 100644 --- a/src/core/display/Transform.js +++ b/src/core/display/Transform.js @@ -67,10 +67,10 @@ */ updateSkew() { - this._cx = Math.cos(this.rotation - this.skew._y); - this._sx = Math.sin(this.rotation - this.skew._y); - this._cy = Math.cos(this.rotation + (Math.PI / 2) + this.skew._x); - this._sy = Math.sin(this.rotation + (Math.PI / 2) + this.skew._x); + this._cx = Math.cos(this.rotation + this.skew._y); + this._sx = Math.sin(this.rotation + this.skew._y); + this._cy = -Math.sin(this.rotation - this.skew._x); // cos, added PI/2 + this._sy = Math.cos(this.rotation - this.skew._x); // sin, added PI/2 } /** diff --git a/src/core/display/TransformStatic.js b/src/core/display/TransformStatic.js index 521f1f2..e763127 100644 --- a/src/core/display/TransformStatic.js +++ b/src/core/display/TransformStatic.js @@ -75,8 +75,8 @@ { this._cx = Math.cos(this.rotation + this.skew._y); this._sx = Math.sin(this.rotation + this.skew._y); - this._cy = Math.cos(this.rotation + (Math.PI / 2) - this.skew._x); - this._sy = Math.sin(this.rotation + (Math.PI / 2) - this.skew._x); + this._cy = -Math.sin(this.rotation - this.skew._x); // cos, added PI/2 + this._sy = Math.cos(this.rotation - this.skew._x); // sin, added PI/2 this._localID ++; } diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e3341fe..0b77477 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -353,10 +353,10 @@ const c = this.c; const d = this.d; - const skewX = Math.atan2(-c, d); + const skewX = -Math.atan2(-c, d); const skewY = Math.atan2(b, a); - const delta = Math.abs(1 - (skewX / skewY)); + const delta = Math.abs(skewX + skewY); if (delta < 0.00001) { diff --git a/src/core/display/Transform.js b/src/core/display/Transform.js index 718d791..183fa0b 100644 --- a/src/core/display/Transform.js +++ b/src/core/display/Transform.js @@ -67,10 +67,10 @@ */ updateSkew() { - this._cx = Math.cos(this.rotation - this.skew._y); - this._sx = Math.sin(this.rotation - this.skew._y); - this._cy = Math.cos(this.rotation + (Math.PI / 2) + this.skew._x); - this._sy = Math.sin(this.rotation + (Math.PI / 2) + this.skew._x); + this._cx = Math.cos(this.rotation + this.skew._y); + this._sx = Math.sin(this.rotation + this.skew._y); + this._cy = -Math.sin(this.rotation - this.skew._x); // cos, added PI/2 + this._sy = Math.cos(this.rotation - this.skew._x); // sin, added PI/2 } /** diff --git a/src/core/display/TransformStatic.js b/src/core/display/TransformStatic.js index 521f1f2..e763127 100644 --- a/src/core/display/TransformStatic.js +++ b/src/core/display/TransformStatic.js @@ -75,8 +75,8 @@ { this._cx = Math.cos(this.rotation + this.skew._y); this._sx = Math.sin(this.rotation + this.skew._y); - this._cy = Math.cos(this.rotation + (Math.PI / 2) - this.skew._x); - this._sy = Math.sin(this.rotation + (Math.PI / 2) - this.skew._x); + this._cy = -Math.sin(this.rotation - this.skew._x); // cos, added PI/2 + this._sy = Math.cos(this.rotation - this.skew._x); // sin, added PI/2 this._localID ++; } diff --git a/src/core/math/Matrix.js b/src/core/math/Matrix.js index e3341fe..0b77477 100644 --- a/src/core/math/Matrix.js +++ b/src/core/math/Matrix.js @@ -353,10 +353,10 @@ const c = this.c; const d = this.d; - const skewX = Math.atan2(-c, d); + const skewX = -Math.atan2(-c, d); const skewY = Math.atan2(b, a); - const delta = Math.abs(1 - (skewX / skewY)); + const delta = Math.abs(skewX + skewY); if (delta < 0.00001) { diff --git a/test/core/TransformStatic.js b/test/core/TransformStatic.js index fb330aa..bb9607a 100644 --- a/test/core/TransformStatic.js +++ b/test/core/TransformStatic.js @@ -4,7 +4,7 @@ { describe('setFromMatrix', () => { - it('should decompose correct rotation', () => + it('should decompose negative scale into rotation', () => { const eps = 1e-3; @@ -13,8 +13,8 @@ const otherTransform = new PIXI.TransformStatic(); transform.position.set(20, 10); - transform.scale.set(2, -3); - transform.rotation = Math.PI / 4; + transform.scale.set(-2, -3); + transform.rotation = Math.PI / 6; transform.updateTransform(parent); otherTransform.setFromMatrix(transform.worldTransform); @@ -26,10 +26,38 @@ expect(position.x).to.be.closeTo(20, eps); expect(position.y).to.be.closeTo(10, eps); expect(scale.x).to.be.closeTo(2, eps); - expect(scale.y).to.be.closeTo(-3, eps); - expect(skew.x).to.be.equal(0); - expect(skew.y).to.be.equal(0); - expect(otherTransform.rotation).to.be.closeTo(Math.PI / 4, eps); + expect(scale.y).to.be.closeTo(3, eps); + expect(skew.x).to.equal(0); + expect(skew.y).to.equal(0); + expect(otherTransform.rotation).to.be.closeTo(-5 * Math.PI / 6, eps); + }); + + it('should decompose mirror into skew', () => + { + const eps = 1e-3; + + const transform = new PIXI.TransformStatic(); + const parent = new PIXI.TransformStatic(); + const otherTransform = new PIXI.TransformStatic(); + + transform.position.set(20, 10); + transform.scale.set(2, -3); + transform.rotation = Math.PI / 6; + transform.updateTransform(parent); + + otherTransform.setFromMatrix(transform.worldTransform); + + const position = otherTransform.position; + const scale = otherTransform.scale; + const skew = otherTransform.skew; + + expect(position.x).to.be.closeTo(20, eps); + expect(position.y).to.be.closeTo(10, eps); + expect(scale.x).to.be.closeTo(2, eps); + expect(scale.y).to.be.closeTo(3, eps); + expect(skew.x).to.be.closeTo(5 * Math.PI / 6, eps); + expect(skew.y).to.be.closeTo(Math.PI / 6, eps); + expect(otherTransform.rotation).to.equal(0); }); it('should apply skew before scale, like in adobe animate and spine', () => @@ -66,8 +94,8 @@ expect(position.y).to.be.closeTo(313.95, eps); expect(scale.x).to.be.closeTo(0.572, eps); expect(scale.y).to.be.closeTo(4.101, eps); - expect(skew.x).to.be.equal(-0.873); - expect(skew.y).to.be.equal(0.175); + expect(skew.x).to.be.closeTo(-0.873, eps); + expect(skew.y).to.be.closeTo(0.175, eps); expect(otherTransform.rotation).to.be.equal(0); }); });