Skip to content

Commit 91f7e27

Browse files
committed
Transform.getWorldTransformMatrix has been recoded to iterate the transform parents correctly, applying the matrix multiplications as it goes. This (along with some changes in the Input Manager) fix the issue with Game Objects inside of Containers failing hit tests between certain angles. Fix phaserjs#3920
1 parent 0c4de35 commit 91f7e27

3 files changed

Lines changed: 20 additions & 42 deletions

File tree

src/gameobjects/components/Transform.js

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -427,12 +427,14 @@ var Transform = {
427427
* @since 3.4.0
428428
*
429429
* @param {Phaser.GameObjects.Components.TransformMatrix} [tempMatrix] - The matrix to populate with the values from this Game Object.
430+
* @param {Phaser.GameObjects.Components.TransformMatrix} [parentMatrix] - A temporary matrix to hold parent values during the calculations.
430431
*
431432
* @return {Phaser.GameObjects.Components.TransformMatrix} The populated Transform Matrix.
432433
*/
433-
getWorldTransformMatrix: function (tempMatrix)
434+
getWorldTransformMatrix: function (tempMatrix, parentMatrix)
434435
{
435436
if (tempMatrix === undefined) { tempMatrix = new TransformMatrix(); }
437+
if (parentMatrix === undefined) { parentMatrix = new TransformMatrix(); }
436438

437439
var parent = this.parentContainer;
438440

@@ -441,31 +443,17 @@ var Transform = {
441443
return this.getLocalTransformMatrix(tempMatrix);
442444
}
443445

444-
var parents = [];
445-
446+
tempMatrix.applyITRS(this.x, this.y, this._rotation, this._scaleX, this._scaleY);
447+
446448
while (parent)
447449
{
448-
parents.unshift(parent);
449-
parent = parent.parentContainer;
450-
}
450+
parentMatrix.applyITRS(parent.x, parent.y, parent._rotation, parent._scaleX, parent._scaleY);
451451

452-
tempMatrix.loadIdentity();
452+
parentMatrix.multiply(tempMatrix, tempMatrix);
453453

454-
var length = parents.length;
455-
456-
for (var i = 0; i < length; ++i)
457-
{
458-
parent = parents[i];
459-
460-
tempMatrix.translate(parent.x, parent.y);
461-
tempMatrix.rotate(parent.rotation);
462-
tempMatrix.scale(parent.scaleX, parent.scaleY);
454+
parent = parent.parentContainer;
463455
}
464456

465-
tempMatrix.translate(this.x, this.y);
466-
tempMatrix.rotate(this._rotation);
467-
tempMatrix.scale(this._scaleX, this._scaleY);
468-
469457
return tempMatrix;
470458
}
471459

src/gameobjects/container/Container.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ var Container = new Class({
438438

439439
/**
440440
* Returns the world transform matrix as used for Bounds checks.
441+
*
441442
* The returned matrix is temporal and shouldn't be stored.
442443
*
443444
* @method Phaser.GameObjects.Container#getBoundsTransformMatrix
@@ -447,7 +448,7 @@ var Container = new Class({
447448
*/
448449
getBoundsTransformMatrix: function ()
449450
{
450-
return this.getWorldTransformMatrix(this.tempTransformMatrix);
451+
return this.getWorldTransformMatrix(this.tempTransformMatrix, this.localTransform);
451452
},
452453

453454
/**

src/math/TransformXY.js

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,31 +28,20 @@ var TransformXY = function (x, y, positionX, positionY, rotation, scaleX, scaleY
2828
{
2929
if (output === undefined) { output = new Vector2(); }
3030

31-
// ITRS
31+
var radianSin = Math.sin(rotation);
32+
var radianCos = Math.cos(rotation);
3233

33-
var sr = Math.sin(-rotation);
34-
var cr = Math.cos(-rotation);
35-
36-
var a = cr * scaleX;
37-
var b = -sr * scaleX;
38-
var c = sr * scaleY;
39-
var d = cr * scaleY;
34+
// Rotate and Scale
35+
var a = radianCos * scaleX;
36+
var b = radianSin * scaleX;
37+
var c = -radianSin * scaleY;
38+
var d = radianCos * scaleY;
4039

4140
// Invert
41+
var id = 1 / ((a * d) + (c * -b));
4242

43-
var n = a * d - b * c;
44-
45-
var m0 = d / n;
46-
var m1 = -b / n;
47-
var m2 = -c / n;
48-
var m3 = a / n;
49-
var m4 = (c * positionY - d * positionX) / n;
50-
var m5 = -(a * positionY - b * positionX) / n;
51-
52-
// Transform
53-
54-
output.x = x * m0 + y * m2 + m4;
55-
output.y = x * m1 + y * m3 + m5;
43+
output.x = (d * id * x) + (-c * id * y) + (((positionY * c) - (positionX * d)) * id);
44+
output.y = (a * id * y) + (-b * id * x) + (((-positionY * a) + (positionX * b)) * id);
5645

5746
return output;
5847
};

0 commit comments

Comments
 (0)