diff --git a/src/core/const.js b/src/core/const.js index 57d08b9..3f9d5de 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -309,6 +309,12 @@ HIGH: 'highp' }, + TRANSFORM_MODE:{ + STATIC:0, + DYNAMIC:1, + DEFAULT:0 + }, + // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 SPRITE_BATCH_SIZE: 4096, //nice balance between mobile and desktop machines diff --git a/src/core/const.js b/src/core/const.js index 57d08b9..3f9d5de 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -309,6 +309,12 @@ HIGH: 'highp' }, + TRANSFORM_MODE:{ + STATIC:0, + DYNAMIC:1, + DEFAULT:0 + }, + // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 SPRITE_BATCH_SIZE: 4096, //nice balance between mobile and desktop machines diff --git a/src/core/display/Container.js b/src/core/display/Container.js index 26d9e84..90575c7 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -131,6 +131,9 @@ child.parent = this; + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this.children.push(child); // TODO - lets either do all callbacks or all events.. not both! @@ -366,7 +369,7 @@ return; } - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); //TODO: check render flags, how to process stuff here this.worldAlpha = this.alpha * this.parent.worldAlpha; @@ -468,6 +471,7 @@ var matrixCache = this.transform.worldTransform; this.transform.worldTransform = math.Matrix.IDENTITY; + this.transform._worldID++; for (var i = 0, j = this.children.length; i < j; ++i) { @@ -475,6 +479,7 @@ } this.transform.worldTransform = matrixCache; + this.transform._worldID++; this._currentBounds = null; diff --git a/src/core/const.js b/src/core/const.js index 57d08b9..3f9d5de 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -309,6 +309,12 @@ HIGH: 'highp' }, + TRANSFORM_MODE:{ + STATIC:0, + DYNAMIC:1, + DEFAULT:0 + }, + // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 SPRITE_BATCH_SIZE: 4096, //nice balance between mobile and desktop machines diff --git a/src/core/display/Container.js b/src/core/display/Container.js index 26d9e84..90575c7 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -131,6 +131,9 @@ child.parent = this; + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this.children.push(child); // TODO - lets either do all callbacks or all events.. not both! @@ -366,7 +369,7 @@ return; } - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); //TODO: check render flags, how to process stuff here this.worldAlpha = this.alpha * this.parent.worldAlpha; @@ -468,6 +471,7 @@ var matrixCache = this.transform.worldTransform; this.transform.worldTransform = math.Matrix.IDENTITY; + this.transform._worldID++; for (var i = 0, j = this.children.length; i < j; ++i) { @@ -475,6 +479,7 @@ } this.transform.worldTransform = matrixCache; + this.transform._worldID++; this._currentBounds = null; diff --git a/src/core/display/DisplayObject.js b/src/core/display/DisplayObject.js index 256489f..54a4017 100644 --- a/src/core/display/DisplayObject.js +++ b/src/core/display/DisplayObject.js @@ -1,5 +1,7 @@ var math = require('../math'), EventEmitter = require('eventemitter3'), + CONST = require('../const'), + TransformStatic = require('./TransformStatic'), Transform = require('./Transform'), _tempDisplayObjectParent = new DisplayObject(); @@ -17,12 +19,14 @@ { EventEmitter.call(this); + var TransformClass = CONST.TRANSFORM_MODE.DEFAULT === CONST.TRANSFORM_MODE.STATIC ? TransformStatic : Transform; + //TODO: need to create Transform from factory /** * World transform and local transform of this object. * This will be reworked in v4.1, please do not use it yet unless you know what are you doing! */ - this.transform = new Transform(); + this.transform = new TransformClass(); /** * The opacity of the object. @@ -322,7 +326,7 @@ */ DisplayObject.prototype.updateTransform = function () { - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); // multiply the alphas.. this.worldAlpha = this.alpha * this.parent.worldAlpha; }; diff --git a/src/core/const.js b/src/core/const.js index 57d08b9..3f9d5de 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -309,6 +309,12 @@ HIGH: 'highp' }, + TRANSFORM_MODE:{ + STATIC:0, + DYNAMIC:1, + DEFAULT:0 + }, + // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 SPRITE_BATCH_SIZE: 4096, //nice balance between mobile and desktop machines diff --git a/src/core/display/Container.js b/src/core/display/Container.js index 26d9e84..90575c7 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -131,6 +131,9 @@ child.parent = this; + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this.children.push(child); // TODO - lets either do all callbacks or all events.. not both! @@ -366,7 +369,7 @@ return; } - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); //TODO: check render flags, how to process stuff here this.worldAlpha = this.alpha * this.parent.worldAlpha; @@ -468,6 +471,7 @@ var matrixCache = this.transform.worldTransform; this.transform.worldTransform = math.Matrix.IDENTITY; + this.transform._worldID++; for (var i = 0, j = this.children.length; i < j; ++i) { @@ -475,6 +479,7 @@ } this.transform.worldTransform = matrixCache; + this.transform._worldID++; this._currentBounds = null; diff --git a/src/core/display/DisplayObject.js b/src/core/display/DisplayObject.js index 256489f..54a4017 100644 --- a/src/core/display/DisplayObject.js +++ b/src/core/display/DisplayObject.js @@ -1,5 +1,7 @@ var math = require('../math'), EventEmitter = require('eventemitter3'), + CONST = require('../const'), + TransformStatic = require('./TransformStatic'), Transform = require('./Transform'), _tempDisplayObjectParent = new DisplayObject(); @@ -17,12 +19,14 @@ { EventEmitter.call(this); + var TransformClass = CONST.TRANSFORM_MODE.DEFAULT === CONST.TRANSFORM_MODE.STATIC ? TransformStatic : Transform; + //TODO: need to create Transform from factory /** * World transform and local transform of this object. * This will be reworked in v4.1, please do not use it yet unless you know what are you doing! */ - this.transform = new Transform(); + this.transform = new TransformClass(); /** * The opacity of the object. @@ -322,7 +326,7 @@ */ DisplayObject.prototype.updateTransform = function () { - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); // multiply the alphas.. this.worldAlpha = this.alpha * this.parent.worldAlpha; }; diff --git a/src/core/display/ObservablePoint.js b/src/core/display/ObservablePoint.js deleted file mode 100644 index 836fcdd..0000000 --- a/src/core/display/ObservablePoint.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * The Point object represents a location in a two-dimensional coordinate system, where x represents - * the horizontal axis and y represents the vertical axis. - * An observable point is a point that triggers a callback when the point's position is changed. - * - * @class - * @memberof PIXI - * @param cb {Function} callback when changed - * @param scope {Object} owner of callback - * @param [x=0] {number} position of the point on the x axis - * @param [y=0] {number} position of the point on the y axis - */ -function ObservablePoint(cb, scope, x, y) -{ - this._x = x || 0; - this._y = y || 0; - - this.cb = cb; - this.scope = scope; -} - -ObservablePoint.prototype.constructor = ObservablePoint; -module.exports = ObservablePoint; - - - -Object.defineProperties(ObservablePoint.prototype, { - /** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @member {number} - * @memberof PIXI.ObservablePoint# - */ - x: { - get: function () - { - return this._x; - }, - set: function (value) - { - if (this._x !== value) { - this._x = value; - this.cb.call(this.scope); - } - } - }, - /** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @member {number} - * @memberof PIXI.ObservablePoint# - */ - y: { - get: function () - { - return this._y; - }, - set: function (value) - { - if (this._y !== value) { - this._y = value; - this.cb.call(this.scope); - } - } - } -}); - -/** - * Sets the point to a new x and y position. - * If y is omitted, both x and y will be set to x. - * - * @param [x=0] {number} position of the point on the x axis - * @param [y=0] {number} position of the point on the y axis - */ -ObservablePoint.prototype.set = function (x, y) -{ - var _x = x || 0; - var _y = y || ( (y !== 0) ? _x : 0 ); - if (this._x !== _x || this._y !== _y) - { - this._x = _x; - this._y = _y; - this.cb.call(this.scope); - } -}; - -/** - * Copies the data from another point - * - * @param point {PIXI.Point|{PIXI.ObservablePoint} point to copy from - */ -ObservablePoint.prototype.copy = function (point) -{ - if (this._x !== point.x || this._y !== point.y) - { - this._x = point.x; - this._y = point.y; - this.cb.call(this.scope); - } -}; diff --git a/src/core/const.js b/src/core/const.js index 57d08b9..3f9d5de 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -309,6 +309,12 @@ HIGH: 'highp' }, + TRANSFORM_MODE:{ + STATIC:0, + DYNAMIC:1, + DEFAULT:0 + }, + // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 SPRITE_BATCH_SIZE: 4096, //nice balance between mobile and desktop machines diff --git a/src/core/display/Container.js b/src/core/display/Container.js index 26d9e84..90575c7 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -131,6 +131,9 @@ child.parent = this; + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this.children.push(child); // TODO - lets either do all callbacks or all events.. not both! @@ -366,7 +369,7 @@ return; } - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); //TODO: check render flags, how to process stuff here this.worldAlpha = this.alpha * this.parent.worldAlpha; @@ -468,6 +471,7 @@ var matrixCache = this.transform.worldTransform; this.transform.worldTransform = math.Matrix.IDENTITY; + this.transform._worldID++; for (var i = 0, j = this.children.length; i < j; ++i) { @@ -475,6 +479,7 @@ } this.transform.worldTransform = matrixCache; + this.transform._worldID++; this._currentBounds = null; diff --git a/src/core/display/DisplayObject.js b/src/core/display/DisplayObject.js index 256489f..54a4017 100644 --- a/src/core/display/DisplayObject.js +++ b/src/core/display/DisplayObject.js @@ -1,5 +1,7 @@ var math = require('../math'), EventEmitter = require('eventemitter3'), + CONST = require('../const'), + TransformStatic = require('./TransformStatic'), Transform = require('./Transform'), _tempDisplayObjectParent = new DisplayObject(); @@ -17,12 +19,14 @@ { EventEmitter.call(this); + var TransformClass = CONST.TRANSFORM_MODE.DEFAULT === CONST.TRANSFORM_MODE.STATIC ? TransformStatic : Transform; + //TODO: need to create Transform from factory /** * World transform and local transform of this object. * This will be reworked in v4.1, please do not use it yet unless you know what are you doing! */ - this.transform = new Transform(); + this.transform = new TransformClass(); /** * The opacity of the object. @@ -322,7 +326,7 @@ */ DisplayObject.prototype.updateTransform = function () { - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); // multiply the alphas.. this.worldAlpha = this.alpha * this.parent.worldAlpha; }; diff --git a/src/core/display/ObservablePoint.js b/src/core/display/ObservablePoint.js deleted file mode 100644 index 836fcdd..0000000 --- a/src/core/display/ObservablePoint.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * The Point object represents a location in a two-dimensional coordinate system, where x represents - * the horizontal axis and y represents the vertical axis. - * An observable point is a point that triggers a callback when the point's position is changed. - * - * @class - * @memberof PIXI - * @param cb {Function} callback when changed - * @param scope {Object} owner of callback - * @param [x=0] {number} position of the point on the x axis - * @param [y=0] {number} position of the point on the y axis - */ -function ObservablePoint(cb, scope, x, y) -{ - this._x = x || 0; - this._y = y || 0; - - this.cb = cb; - this.scope = scope; -} - -ObservablePoint.prototype.constructor = ObservablePoint; -module.exports = ObservablePoint; - - - -Object.defineProperties(ObservablePoint.prototype, { - /** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @member {number} - * @memberof PIXI.ObservablePoint# - */ - x: { - get: function () - { - return this._x; - }, - set: function (value) - { - if (this._x !== value) { - this._x = value; - this.cb.call(this.scope); - } - } - }, - /** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @member {number} - * @memberof PIXI.ObservablePoint# - */ - y: { - get: function () - { - return this._y; - }, - set: function (value) - { - if (this._y !== value) { - this._y = value; - this.cb.call(this.scope); - } - } - } -}); - -/** - * Sets the point to a new x and y position. - * If y is omitted, both x and y will be set to x. - * - * @param [x=0] {number} position of the point on the x axis - * @param [y=0] {number} position of the point on the y axis - */ -ObservablePoint.prototype.set = function (x, y) -{ - var _x = x || 0; - var _y = y || ( (y !== 0) ? _x : 0 ); - if (this._x !== _x || this._y !== _y) - { - this._x = _x; - this._y = _y; - this.cb.call(this.scope); - } -}; - -/** - * Copies the data from another point - * - * @param point {PIXI.Point|{PIXI.ObservablePoint} point to copy from - */ -ObservablePoint.prototype.copy = function (point) -{ - if (this._x !== point.x || this._y !== point.y) - { - this._x = point.x; - this._y = point.y; - this.cb.call(this.scope); - } -}; diff --git a/src/core/display/Transform.js b/src/core/display/Transform.js index 2d1e90f..ee8bafb 100644 --- a/src/core/display/Transform.js +++ b/src/core/display/Transform.js @@ -1,5 +1,4 @@ -var math = require('../math'), - ObservablePoint = require('./ObservablePoint'); +var math = require('../math'); /** @@ -35,7 +34,7 @@ this.scale = new math.Point(1,1); - this.skew = new ObservablePoint(this.updateSkew, this, 0,0); + this.skew = new math.ObservablePoint(this.updateSkew, this, 0,0); /** * The pivot point of the displayObject that it rotates around @@ -60,6 +59,8 @@ this._dirty = false; this.updated = true; + + this._worldID = 0; } Transform.prototype.constructor = Transform; @@ -105,15 +106,10 @@ wt.d = lt.c * pt.b + lt.d * pt.d; wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; -}; -Transform.prototype.updateChildTransform = function (childTransform) -{ - childTransform.updateTransform(this); - return childTransform; + this._worldID ++; }; - /** * Decomposes a matrix and sets the transforms properties based on it. * @param {Matrix} diff --git a/src/core/const.js b/src/core/const.js index 57d08b9..3f9d5de 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -309,6 +309,12 @@ HIGH: 'highp' }, + TRANSFORM_MODE:{ + STATIC:0, + DYNAMIC:1, + DEFAULT:0 + }, + // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 SPRITE_BATCH_SIZE: 4096, //nice balance between mobile and desktop machines diff --git a/src/core/display/Container.js b/src/core/display/Container.js index 26d9e84..90575c7 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -131,6 +131,9 @@ child.parent = this; + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this.children.push(child); // TODO - lets either do all callbacks or all events.. not both! @@ -366,7 +369,7 @@ return; } - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); //TODO: check render flags, how to process stuff here this.worldAlpha = this.alpha * this.parent.worldAlpha; @@ -468,6 +471,7 @@ var matrixCache = this.transform.worldTransform; this.transform.worldTransform = math.Matrix.IDENTITY; + this.transform._worldID++; for (var i = 0, j = this.children.length; i < j; ++i) { @@ -475,6 +479,7 @@ } this.transform.worldTransform = matrixCache; + this.transform._worldID++; this._currentBounds = null; diff --git a/src/core/display/DisplayObject.js b/src/core/display/DisplayObject.js index 256489f..54a4017 100644 --- a/src/core/display/DisplayObject.js +++ b/src/core/display/DisplayObject.js @@ -1,5 +1,7 @@ var math = require('../math'), EventEmitter = require('eventemitter3'), + CONST = require('../const'), + TransformStatic = require('./TransformStatic'), Transform = require('./Transform'), _tempDisplayObjectParent = new DisplayObject(); @@ -17,12 +19,14 @@ { EventEmitter.call(this); + var TransformClass = CONST.TRANSFORM_MODE.DEFAULT === CONST.TRANSFORM_MODE.STATIC ? TransformStatic : Transform; + //TODO: need to create Transform from factory /** * World transform and local transform of this object. * This will be reworked in v4.1, please do not use it yet unless you know what are you doing! */ - this.transform = new Transform(); + this.transform = new TransformClass(); /** * The opacity of the object. @@ -322,7 +326,7 @@ */ DisplayObject.prototype.updateTransform = function () { - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); // multiply the alphas.. this.worldAlpha = this.alpha * this.parent.worldAlpha; }; diff --git a/src/core/display/ObservablePoint.js b/src/core/display/ObservablePoint.js deleted file mode 100644 index 836fcdd..0000000 --- a/src/core/display/ObservablePoint.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * The Point object represents a location in a two-dimensional coordinate system, where x represents - * the horizontal axis and y represents the vertical axis. - * An observable point is a point that triggers a callback when the point's position is changed. - * - * @class - * @memberof PIXI - * @param cb {Function} callback when changed - * @param scope {Object} owner of callback - * @param [x=0] {number} position of the point on the x axis - * @param [y=0] {number} position of the point on the y axis - */ -function ObservablePoint(cb, scope, x, y) -{ - this._x = x || 0; - this._y = y || 0; - - this.cb = cb; - this.scope = scope; -} - -ObservablePoint.prototype.constructor = ObservablePoint; -module.exports = ObservablePoint; - - - -Object.defineProperties(ObservablePoint.prototype, { - /** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @member {number} - * @memberof PIXI.ObservablePoint# - */ - x: { - get: function () - { - return this._x; - }, - set: function (value) - { - if (this._x !== value) { - this._x = value; - this.cb.call(this.scope); - } - } - }, - /** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @member {number} - * @memberof PIXI.ObservablePoint# - */ - y: { - get: function () - { - return this._y; - }, - set: function (value) - { - if (this._y !== value) { - this._y = value; - this.cb.call(this.scope); - } - } - } -}); - -/** - * Sets the point to a new x and y position. - * If y is omitted, both x and y will be set to x. - * - * @param [x=0] {number} position of the point on the x axis - * @param [y=0] {number} position of the point on the y axis - */ -ObservablePoint.prototype.set = function (x, y) -{ - var _x = x || 0; - var _y = y || ( (y !== 0) ? _x : 0 ); - if (this._x !== _x || this._y !== _y) - { - this._x = _x; - this._y = _y; - this.cb.call(this.scope); - } -}; - -/** - * Copies the data from another point - * - * @param point {PIXI.Point|{PIXI.ObservablePoint} point to copy from - */ -ObservablePoint.prototype.copy = function (point) -{ - if (this._x !== point.x || this._y !== point.y) - { - this._x = point.x; - this._y = point.y; - this.cb.call(this.scope); - } -}; diff --git a/src/core/display/Transform.js b/src/core/display/Transform.js index 2d1e90f..ee8bafb 100644 --- a/src/core/display/Transform.js +++ b/src/core/display/Transform.js @@ -1,5 +1,4 @@ -var math = require('../math'), - ObservablePoint = require('./ObservablePoint'); +var math = require('../math'); /** @@ -35,7 +34,7 @@ this.scale = new math.Point(1,1); - this.skew = new ObservablePoint(this.updateSkew, this, 0,0); + this.skew = new math.ObservablePoint(this.updateSkew, this, 0,0); /** * The pivot point of the displayObject that it rotates around @@ -60,6 +59,8 @@ this._dirty = false; this.updated = true; + + this._worldID = 0; } Transform.prototype.constructor = Transform; @@ -105,15 +106,10 @@ wt.d = lt.c * pt.b + lt.d * pt.d; wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; -}; -Transform.prototype.updateChildTransform = function (childTransform) -{ - childTransform.updateTransform(this); - return childTransform; + this._worldID ++; }; - /** * Decomposes a matrix and sets the transforms properties based on it. * @param {Matrix} diff --git a/src/core/display/TransformStatic.js b/src/core/display/TransformStatic.js index fcab61b..510b716 100644 --- a/src/core/display/TransformStatic.js +++ b/src/core/display/TransformStatic.js @@ -1,5 +1,4 @@ var math = require('../math'); -var ObservablePoint = require('./ObservablePoint'); /** * Transform that takes care about its versions @@ -24,40 +23,62 @@ * * @member {PIXI.ObservablePoint} */ - this.position = new ObservablePoint(this,0.0); + this.position = new math.ObservablePoint(this.onChange, this,0.0); /** * The scale factor of the object. * * @member {PIXI.ObservablePoint} */ - this.scale = new ObservablePoint(this,1,1); + this.scale = new math.ObservablePoint(this.onChange, this,1,1); /** * The pivot point of the displayObject that it rotates around * * @member {PIXI.ObservablePoint} */ - this.pivot = new ObservablePoint(this,0.0); + this.pivot = new math.ObservablePoint(this.onChange, this,0, 0); /** * The skew amount, on the x and y axis. * * @member {PIXI.ObservablePoint} */ - this.skew = new ObservablePoint(this,0.0); + this.skew = new math.ObservablePoint(this.updateSkew, this,0, 0); this._rotation = 0; + this._sr = Math.sin(0); this._cr = Math.cos(0); + this._cy = Math.cos(0);//skewY); + this._sy = Math.sin(0);//skewY); + this._nsx = Math.sin(0);//skewX); + this._cx = Math.cos(0);//skewX); - this._dirtyLocal = 0; - this._versionLocal = 0; - this._versionGlobal = 0; + + this._localID = 0; + this._currentLocalID = 0; + this._parentID = 0; + this._worldID = 0; } TransformStatic.prototype.constructor = TransformStatic; +TransformStatic.prototype.onChange = function () +{ + this._localID ++; +}; + +TransformStatic.prototype.updateSkew = function () +{ + this._cy = Math.cos(this.skew.y); + this._sy = Math.sin(this.skew.y); + this._nsx = Math.sin(this.skew.x); + this._cx = Math.cos(this.skew.x); + + this._localID ++; +}; + /** * Updates the values of the object and applies the parent's transform. * @param parentTransform {PIXI.Transform} The transform of the parent of this object @@ -69,35 +90,57 @@ var wt = this.worldTransform; var lt = this.localTransform; - if(this._dirtyLocal !== this._versionLocal) + if(this._localID !== this._currentLocalID) { // get the matrix values of the displayobject based on its transform properties.. - lt.a = this._cr * this.scale._x; - lt.b = this._sr * this.scale._x; - lt.c = -this._sr * this.scale._y; - lt.d = this._cr * this.scale._y; + var a,b,c,d; + + a = this._cr * this.scale.x; + b = this._sr * this.scale.x; + c = -this._sr * this.scale.y; + d = this._cr * this.scale.y; + + lt.a = this._cy * a + this._sy * c; + lt.b = this._cy * b + this._sy * d; + lt.c = this._nsx * a + this._cx * c; + lt.d = this._nsx * b + this._cx * d; + lt.tx = this.position._x - (this.pivot._x * lt.a + this.pivot._y * lt.c); lt.ty = this.position._y - (this.pivot._x * lt.b + this.pivot._y * lt.d); - this._dirtyLocal = this._versionLocal; + this._currentLocalID = this._localID; + + // force an update.. + this._parentID = -1; } - // concat the parent matrix with the objects transform. - wt.a = lt.a * pt.a + lt.b * pt.c; - wt.b = lt.a * pt.b + lt.b * pt.d; - wt.c = lt.c * pt.a + lt.d * pt.c; - wt.d = lt.c * pt.b + lt.d * pt.d; - wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; - wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; - this._versionGlobal++; - this.updated = true; + if(this._parentID !== parentTransform._worldID) + { + // concat the parent matrix with the objects transform. + wt.a = lt.a * pt.a + lt.b * pt.c; + wt.b = lt.a * pt.b + lt.b * pt.d; + wt.c = lt.c * pt.a + lt.d * pt.c; + wt.d = lt.c * pt.b + lt.d * pt.d; + wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; + wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; + + this._parentID = parentTransform._worldID; + + // update the id of the transform.. + this._worldID ++; + } }; -TransformStatic.prototype.updateChildTransform = function (childTransform) +/** + * Decomposes a matrix and sets the transforms properties based on it. + * @param {Matrix} + */ +TransformStatic.prototype.setFromMatrix = function (matrix) { - childTransform.updateTransform(this); - return childTransform; + matrix.decompose(this); }; + + Object.defineProperties(TransformStatic.prototype, { /** * The rotation of the object in radians. @@ -112,6 +155,7 @@ this._rotation = value; this._sr = Math.sin(value); this._cr = Math.cos(value); + this._localID ++; } } }); diff --git a/src/core/const.js b/src/core/const.js index 57d08b9..3f9d5de 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -309,6 +309,12 @@ HIGH: 'highp' }, + TRANSFORM_MODE:{ + STATIC:0, + DYNAMIC:1, + DEFAULT:0 + }, + // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 SPRITE_BATCH_SIZE: 4096, //nice balance between mobile and desktop machines diff --git a/src/core/display/Container.js b/src/core/display/Container.js index 26d9e84..90575c7 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -131,6 +131,9 @@ child.parent = this; + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this.children.push(child); // TODO - lets either do all callbacks or all events.. not both! @@ -366,7 +369,7 @@ return; } - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); //TODO: check render flags, how to process stuff here this.worldAlpha = this.alpha * this.parent.worldAlpha; @@ -468,6 +471,7 @@ var matrixCache = this.transform.worldTransform; this.transform.worldTransform = math.Matrix.IDENTITY; + this.transform._worldID++; for (var i = 0, j = this.children.length; i < j; ++i) { @@ -475,6 +479,7 @@ } this.transform.worldTransform = matrixCache; + this.transform._worldID++; this._currentBounds = null; diff --git a/src/core/display/DisplayObject.js b/src/core/display/DisplayObject.js index 256489f..54a4017 100644 --- a/src/core/display/DisplayObject.js +++ b/src/core/display/DisplayObject.js @@ -1,5 +1,7 @@ var math = require('../math'), EventEmitter = require('eventemitter3'), + CONST = require('../const'), + TransformStatic = require('./TransformStatic'), Transform = require('./Transform'), _tempDisplayObjectParent = new DisplayObject(); @@ -17,12 +19,14 @@ { EventEmitter.call(this); + var TransformClass = CONST.TRANSFORM_MODE.DEFAULT === CONST.TRANSFORM_MODE.STATIC ? TransformStatic : Transform; + //TODO: need to create Transform from factory /** * World transform and local transform of this object. * This will be reworked in v4.1, please do not use it yet unless you know what are you doing! */ - this.transform = new Transform(); + this.transform = new TransformClass(); /** * The opacity of the object. @@ -322,7 +326,7 @@ */ DisplayObject.prototype.updateTransform = function () { - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); // multiply the alphas.. this.worldAlpha = this.alpha * this.parent.worldAlpha; }; diff --git a/src/core/display/ObservablePoint.js b/src/core/display/ObservablePoint.js deleted file mode 100644 index 836fcdd..0000000 --- a/src/core/display/ObservablePoint.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * The Point object represents a location in a two-dimensional coordinate system, where x represents - * the horizontal axis and y represents the vertical axis. - * An observable point is a point that triggers a callback when the point's position is changed. - * - * @class - * @memberof PIXI - * @param cb {Function} callback when changed - * @param scope {Object} owner of callback - * @param [x=0] {number} position of the point on the x axis - * @param [y=0] {number} position of the point on the y axis - */ -function ObservablePoint(cb, scope, x, y) -{ - this._x = x || 0; - this._y = y || 0; - - this.cb = cb; - this.scope = scope; -} - -ObservablePoint.prototype.constructor = ObservablePoint; -module.exports = ObservablePoint; - - - -Object.defineProperties(ObservablePoint.prototype, { - /** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @member {number} - * @memberof PIXI.ObservablePoint# - */ - x: { - get: function () - { - return this._x; - }, - set: function (value) - { - if (this._x !== value) { - this._x = value; - this.cb.call(this.scope); - } - } - }, - /** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @member {number} - * @memberof PIXI.ObservablePoint# - */ - y: { - get: function () - { - return this._y; - }, - set: function (value) - { - if (this._y !== value) { - this._y = value; - this.cb.call(this.scope); - } - } - } -}); - -/** - * Sets the point to a new x and y position. - * If y is omitted, both x and y will be set to x. - * - * @param [x=0] {number} position of the point on the x axis - * @param [y=0] {number} position of the point on the y axis - */ -ObservablePoint.prototype.set = function (x, y) -{ - var _x = x || 0; - var _y = y || ( (y !== 0) ? _x : 0 ); - if (this._x !== _x || this._y !== _y) - { - this._x = _x; - this._y = _y; - this.cb.call(this.scope); - } -}; - -/** - * Copies the data from another point - * - * @param point {PIXI.Point|{PIXI.ObservablePoint} point to copy from - */ -ObservablePoint.prototype.copy = function (point) -{ - if (this._x !== point.x || this._y !== point.y) - { - this._x = point.x; - this._y = point.y; - this.cb.call(this.scope); - } -}; diff --git a/src/core/display/Transform.js b/src/core/display/Transform.js index 2d1e90f..ee8bafb 100644 --- a/src/core/display/Transform.js +++ b/src/core/display/Transform.js @@ -1,5 +1,4 @@ -var math = require('../math'), - ObservablePoint = require('./ObservablePoint'); +var math = require('../math'); /** @@ -35,7 +34,7 @@ this.scale = new math.Point(1,1); - this.skew = new ObservablePoint(this.updateSkew, this, 0,0); + this.skew = new math.ObservablePoint(this.updateSkew, this, 0,0); /** * The pivot point of the displayObject that it rotates around @@ -60,6 +59,8 @@ this._dirty = false; this.updated = true; + + this._worldID = 0; } Transform.prototype.constructor = Transform; @@ -105,15 +106,10 @@ wt.d = lt.c * pt.b + lt.d * pt.d; wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; -}; -Transform.prototype.updateChildTransform = function (childTransform) -{ - childTransform.updateTransform(this); - return childTransform; + this._worldID ++; }; - /** * Decomposes a matrix and sets the transforms properties based on it. * @param {Matrix} diff --git a/src/core/display/TransformStatic.js b/src/core/display/TransformStatic.js index fcab61b..510b716 100644 --- a/src/core/display/TransformStatic.js +++ b/src/core/display/TransformStatic.js @@ -1,5 +1,4 @@ var math = require('../math'); -var ObservablePoint = require('./ObservablePoint'); /** * Transform that takes care about its versions @@ -24,40 +23,62 @@ * * @member {PIXI.ObservablePoint} */ - this.position = new ObservablePoint(this,0.0); + this.position = new math.ObservablePoint(this.onChange, this,0.0); /** * The scale factor of the object. * * @member {PIXI.ObservablePoint} */ - this.scale = new ObservablePoint(this,1,1); + this.scale = new math.ObservablePoint(this.onChange, this,1,1); /** * The pivot point of the displayObject that it rotates around * * @member {PIXI.ObservablePoint} */ - this.pivot = new ObservablePoint(this,0.0); + this.pivot = new math.ObservablePoint(this.onChange, this,0, 0); /** * The skew amount, on the x and y axis. * * @member {PIXI.ObservablePoint} */ - this.skew = new ObservablePoint(this,0.0); + this.skew = new math.ObservablePoint(this.updateSkew, this,0, 0); this._rotation = 0; + this._sr = Math.sin(0); this._cr = Math.cos(0); + this._cy = Math.cos(0);//skewY); + this._sy = Math.sin(0);//skewY); + this._nsx = Math.sin(0);//skewX); + this._cx = Math.cos(0);//skewX); - this._dirtyLocal = 0; - this._versionLocal = 0; - this._versionGlobal = 0; + + this._localID = 0; + this._currentLocalID = 0; + this._parentID = 0; + this._worldID = 0; } TransformStatic.prototype.constructor = TransformStatic; +TransformStatic.prototype.onChange = function () +{ + this._localID ++; +}; + +TransformStatic.prototype.updateSkew = function () +{ + this._cy = Math.cos(this.skew.y); + this._sy = Math.sin(this.skew.y); + this._nsx = Math.sin(this.skew.x); + this._cx = Math.cos(this.skew.x); + + this._localID ++; +}; + /** * Updates the values of the object and applies the parent's transform. * @param parentTransform {PIXI.Transform} The transform of the parent of this object @@ -69,35 +90,57 @@ var wt = this.worldTransform; var lt = this.localTransform; - if(this._dirtyLocal !== this._versionLocal) + if(this._localID !== this._currentLocalID) { // get the matrix values of the displayobject based on its transform properties.. - lt.a = this._cr * this.scale._x; - lt.b = this._sr * this.scale._x; - lt.c = -this._sr * this.scale._y; - lt.d = this._cr * this.scale._y; + var a,b,c,d; + + a = this._cr * this.scale.x; + b = this._sr * this.scale.x; + c = -this._sr * this.scale.y; + d = this._cr * this.scale.y; + + lt.a = this._cy * a + this._sy * c; + lt.b = this._cy * b + this._sy * d; + lt.c = this._nsx * a + this._cx * c; + lt.d = this._nsx * b + this._cx * d; + lt.tx = this.position._x - (this.pivot._x * lt.a + this.pivot._y * lt.c); lt.ty = this.position._y - (this.pivot._x * lt.b + this.pivot._y * lt.d); - this._dirtyLocal = this._versionLocal; + this._currentLocalID = this._localID; + + // force an update.. + this._parentID = -1; } - // concat the parent matrix with the objects transform. - wt.a = lt.a * pt.a + lt.b * pt.c; - wt.b = lt.a * pt.b + lt.b * pt.d; - wt.c = lt.c * pt.a + lt.d * pt.c; - wt.d = lt.c * pt.b + lt.d * pt.d; - wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; - wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; - this._versionGlobal++; - this.updated = true; + if(this._parentID !== parentTransform._worldID) + { + // concat the parent matrix with the objects transform. + wt.a = lt.a * pt.a + lt.b * pt.c; + wt.b = lt.a * pt.b + lt.b * pt.d; + wt.c = lt.c * pt.a + lt.d * pt.c; + wt.d = lt.c * pt.b + lt.d * pt.d; + wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; + wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; + + this._parentID = parentTransform._worldID; + + // update the id of the transform.. + this._worldID ++; + } }; -TransformStatic.prototype.updateChildTransform = function (childTransform) +/** + * Decomposes a matrix and sets the transforms properties based on it. + * @param {Matrix} + */ +TransformStatic.prototype.setFromMatrix = function (matrix) { - childTransform.updateTransform(this); - return childTransform; + matrix.decompose(this); }; + + Object.defineProperties(TransformStatic.prototype, { /** * The rotation of the object in radians. @@ -112,6 +155,7 @@ this._rotation = value; this._sr = Math.sin(value); this._cr = Math.cos(value); + this._localID ++; } } }); diff --git a/src/core/math/ObservablePoint.js b/src/core/math/ObservablePoint.js new file mode 100644 index 0000000..836fcdd --- /dev/null +++ b/src/core/math/ObservablePoint.js @@ -0,0 +1,100 @@ +/** + * The Point object represents a location in a two-dimensional coordinate system, where x represents + * the horizontal axis and y represents the vertical axis. + * An observable point is a point that triggers a callback when the point's position is changed. + * + * @class + * @memberof PIXI + * @param cb {Function} callback when changed + * @param scope {Object} owner of callback + * @param [x=0] {number} position of the point on the x axis + * @param [y=0] {number} position of the point on the y axis + */ +function ObservablePoint(cb, scope, x, y) +{ + this._x = x || 0; + this._y = y || 0; + + this.cb = cb; + this.scope = scope; +} + +ObservablePoint.prototype.constructor = ObservablePoint; +module.exports = ObservablePoint; + + + +Object.defineProperties(ObservablePoint.prototype, { + /** + * The position of the displayObject on the x axis relative to the local coordinates of the parent. + * + * @member {number} + * @memberof PIXI.ObservablePoint# + */ + x: { + get: function () + { + return this._x; + }, + set: function (value) + { + if (this._x !== value) { + this._x = value; + this.cb.call(this.scope); + } + } + }, + /** + * The position of the displayObject on the x axis relative to the local coordinates of the parent. + * + * @member {number} + * @memberof PIXI.ObservablePoint# + */ + y: { + get: function () + { + return this._y; + }, + set: function (value) + { + if (this._y !== value) { + this._y = value; + this.cb.call(this.scope); + } + } + } +}); + +/** + * Sets the point to a new x and y position. + * If y is omitted, both x and y will be set to x. + * + * @param [x=0] {number} position of the point on the x axis + * @param [y=0] {number} position of the point on the y axis + */ +ObservablePoint.prototype.set = function (x, y) +{ + var _x = x || 0; + var _y = y || ( (y !== 0) ? _x : 0 ); + if (this._x !== _x || this._y !== _y) + { + this._x = _x; + this._y = _y; + this.cb.call(this.scope); + } +}; + +/** + * Copies the data from another point + * + * @param point {PIXI.Point|{PIXI.ObservablePoint} point to copy from + */ +ObservablePoint.prototype.copy = function (point) +{ + if (this._x !== point.x || this._y !== point.y) + { + this._x = point.x; + this._y = point.y; + this.cb.call(this.scope); + } +}; diff --git a/src/core/const.js b/src/core/const.js index 57d08b9..3f9d5de 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -309,6 +309,12 @@ HIGH: 'highp' }, + TRANSFORM_MODE:{ + STATIC:0, + DYNAMIC:1, + DEFAULT:0 + }, + // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 SPRITE_BATCH_SIZE: 4096, //nice balance between mobile and desktop machines diff --git a/src/core/display/Container.js b/src/core/display/Container.js index 26d9e84..90575c7 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -131,6 +131,9 @@ child.parent = this; + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this.children.push(child); // TODO - lets either do all callbacks or all events.. not both! @@ -366,7 +369,7 @@ return; } - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); //TODO: check render flags, how to process stuff here this.worldAlpha = this.alpha * this.parent.worldAlpha; @@ -468,6 +471,7 @@ var matrixCache = this.transform.worldTransform; this.transform.worldTransform = math.Matrix.IDENTITY; + this.transform._worldID++; for (var i = 0, j = this.children.length; i < j; ++i) { @@ -475,6 +479,7 @@ } this.transform.worldTransform = matrixCache; + this.transform._worldID++; this._currentBounds = null; diff --git a/src/core/display/DisplayObject.js b/src/core/display/DisplayObject.js index 256489f..54a4017 100644 --- a/src/core/display/DisplayObject.js +++ b/src/core/display/DisplayObject.js @@ -1,5 +1,7 @@ var math = require('../math'), EventEmitter = require('eventemitter3'), + CONST = require('../const'), + TransformStatic = require('./TransformStatic'), Transform = require('./Transform'), _tempDisplayObjectParent = new DisplayObject(); @@ -17,12 +19,14 @@ { EventEmitter.call(this); + var TransformClass = CONST.TRANSFORM_MODE.DEFAULT === CONST.TRANSFORM_MODE.STATIC ? TransformStatic : Transform; + //TODO: need to create Transform from factory /** * World transform and local transform of this object. * This will be reworked in v4.1, please do not use it yet unless you know what are you doing! */ - this.transform = new Transform(); + this.transform = new TransformClass(); /** * The opacity of the object. @@ -322,7 +326,7 @@ */ DisplayObject.prototype.updateTransform = function () { - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); // multiply the alphas.. this.worldAlpha = this.alpha * this.parent.worldAlpha; }; diff --git a/src/core/display/ObservablePoint.js b/src/core/display/ObservablePoint.js deleted file mode 100644 index 836fcdd..0000000 --- a/src/core/display/ObservablePoint.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * The Point object represents a location in a two-dimensional coordinate system, where x represents - * the horizontal axis and y represents the vertical axis. - * An observable point is a point that triggers a callback when the point's position is changed. - * - * @class - * @memberof PIXI - * @param cb {Function} callback when changed - * @param scope {Object} owner of callback - * @param [x=0] {number} position of the point on the x axis - * @param [y=0] {number} position of the point on the y axis - */ -function ObservablePoint(cb, scope, x, y) -{ - this._x = x || 0; - this._y = y || 0; - - this.cb = cb; - this.scope = scope; -} - -ObservablePoint.prototype.constructor = ObservablePoint; -module.exports = ObservablePoint; - - - -Object.defineProperties(ObservablePoint.prototype, { - /** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @member {number} - * @memberof PIXI.ObservablePoint# - */ - x: { - get: function () - { - return this._x; - }, - set: function (value) - { - if (this._x !== value) { - this._x = value; - this.cb.call(this.scope); - } - } - }, - /** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @member {number} - * @memberof PIXI.ObservablePoint# - */ - y: { - get: function () - { - return this._y; - }, - set: function (value) - { - if (this._y !== value) { - this._y = value; - this.cb.call(this.scope); - } - } - } -}); - -/** - * Sets the point to a new x and y position. - * If y is omitted, both x and y will be set to x. - * - * @param [x=0] {number} position of the point on the x axis - * @param [y=0] {number} position of the point on the y axis - */ -ObservablePoint.prototype.set = function (x, y) -{ - var _x = x || 0; - var _y = y || ( (y !== 0) ? _x : 0 ); - if (this._x !== _x || this._y !== _y) - { - this._x = _x; - this._y = _y; - this.cb.call(this.scope); - } -}; - -/** - * Copies the data from another point - * - * @param point {PIXI.Point|{PIXI.ObservablePoint} point to copy from - */ -ObservablePoint.prototype.copy = function (point) -{ - if (this._x !== point.x || this._y !== point.y) - { - this._x = point.x; - this._y = point.y; - this.cb.call(this.scope); - } -}; diff --git a/src/core/display/Transform.js b/src/core/display/Transform.js index 2d1e90f..ee8bafb 100644 --- a/src/core/display/Transform.js +++ b/src/core/display/Transform.js @@ -1,5 +1,4 @@ -var math = require('../math'), - ObservablePoint = require('./ObservablePoint'); +var math = require('../math'); /** @@ -35,7 +34,7 @@ this.scale = new math.Point(1,1); - this.skew = new ObservablePoint(this.updateSkew, this, 0,0); + this.skew = new math.ObservablePoint(this.updateSkew, this, 0,0); /** * The pivot point of the displayObject that it rotates around @@ -60,6 +59,8 @@ this._dirty = false; this.updated = true; + + this._worldID = 0; } Transform.prototype.constructor = Transform; @@ -105,15 +106,10 @@ wt.d = lt.c * pt.b + lt.d * pt.d; wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; -}; -Transform.prototype.updateChildTransform = function (childTransform) -{ - childTransform.updateTransform(this); - return childTransform; + this._worldID ++; }; - /** * Decomposes a matrix and sets the transforms properties based on it. * @param {Matrix} diff --git a/src/core/display/TransformStatic.js b/src/core/display/TransformStatic.js index fcab61b..510b716 100644 --- a/src/core/display/TransformStatic.js +++ b/src/core/display/TransformStatic.js @@ -1,5 +1,4 @@ var math = require('../math'); -var ObservablePoint = require('./ObservablePoint'); /** * Transform that takes care about its versions @@ -24,40 +23,62 @@ * * @member {PIXI.ObservablePoint} */ - this.position = new ObservablePoint(this,0.0); + this.position = new math.ObservablePoint(this.onChange, this,0.0); /** * The scale factor of the object. * * @member {PIXI.ObservablePoint} */ - this.scale = new ObservablePoint(this,1,1); + this.scale = new math.ObservablePoint(this.onChange, this,1,1); /** * The pivot point of the displayObject that it rotates around * * @member {PIXI.ObservablePoint} */ - this.pivot = new ObservablePoint(this,0.0); + this.pivot = new math.ObservablePoint(this.onChange, this,0, 0); /** * The skew amount, on the x and y axis. * * @member {PIXI.ObservablePoint} */ - this.skew = new ObservablePoint(this,0.0); + this.skew = new math.ObservablePoint(this.updateSkew, this,0, 0); this._rotation = 0; + this._sr = Math.sin(0); this._cr = Math.cos(0); + this._cy = Math.cos(0);//skewY); + this._sy = Math.sin(0);//skewY); + this._nsx = Math.sin(0);//skewX); + this._cx = Math.cos(0);//skewX); - this._dirtyLocal = 0; - this._versionLocal = 0; - this._versionGlobal = 0; + + this._localID = 0; + this._currentLocalID = 0; + this._parentID = 0; + this._worldID = 0; } TransformStatic.prototype.constructor = TransformStatic; +TransformStatic.prototype.onChange = function () +{ + this._localID ++; +}; + +TransformStatic.prototype.updateSkew = function () +{ + this._cy = Math.cos(this.skew.y); + this._sy = Math.sin(this.skew.y); + this._nsx = Math.sin(this.skew.x); + this._cx = Math.cos(this.skew.x); + + this._localID ++; +}; + /** * Updates the values of the object and applies the parent's transform. * @param parentTransform {PIXI.Transform} The transform of the parent of this object @@ -69,35 +90,57 @@ var wt = this.worldTransform; var lt = this.localTransform; - if(this._dirtyLocal !== this._versionLocal) + if(this._localID !== this._currentLocalID) { // get the matrix values of the displayobject based on its transform properties.. - lt.a = this._cr * this.scale._x; - lt.b = this._sr * this.scale._x; - lt.c = -this._sr * this.scale._y; - lt.d = this._cr * this.scale._y; + var a,b,c,d; + + a = this._cr * this.scale.x; + b = this._sr * this.scale.x; + c = -this._sr * this.scale.y; + d = this._cr * this.scale.y; + + lt.a = this._cy * a + this._sy * c; + lt.b = this._cy * b + this._sy * d; + lt.c = this._nsx * a + this._cx * c; + lt.d = this._nsx * b + this._cx * d; + lt.tx = this.position._x - (this.pivot._x * lt.a + this.pivot._y * lt.c); lt.ty = this.position._y - (this.pivot._x * lt.b + this.pivot._y * lt.d); - this._dirtyLocal = this._versionLocal; + this._currentLocalID = this._localID; + + // force an update.. + this._parentID = -1; } - // concat the parent matrix with the objects transform. - wt.a = lt.a * pt.a + lt.b * pt.c; - wt.b = lt.a * pt.b + lt.b * pt.d; - wt.c = lt.c * pt.a + lt.d * pt.c; - wt.d = lt.c * pt.b + lt.d * pt.d; - wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; - wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; - this._versionGlobal++; - this.updated = true; + if(this._parentID !== parentTransform._worldID) + { + // concat the parent matrix with the objects transform. + wt.a = lt.a * pt.a + lt.b * pt.c; + wt.b = lt.a * pt.b + lt.b * pt.d; + wt.c = lt.c * pt.a + lt.d * pt.c; + wt.d = lt.c * pt.b + lt.d * pt.d; + wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; + wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; + + this._parentID = parentTransform._worldID; + + // update the id of the transform.. + this._worldID ++; + } }; -TransformStatic.prototype.updateChildTransform = function (childTransform) +/** + * Decomposes a matrix and sets the transforms properties based on it. + * @param {Matrix} + */ +TransformStatic.prototype.setFromMatrix = function (matrix) { - childTransform.updateTransform(this); - return childTransform; + matrix.decompose(this); }; + + Object.defineProperties(TransformStatic.prototype, { /** * The rotation of the object in radians. @@ -112,6 +155,7 @@ this._rotation = value; this._sr = Math.sin(value); this._cr = Math.cos(value); + this._localID ++; } } }); diff --git a/src/core/math/ObservablePoint.js b/src/core/math/ObservablePoint.js new file mode 100644 index 0000000..836fcdd --- /dev/null +++ b/src/core/math/ObservablePoint.js @@ -0,0 +1,100 @@ +/** + * The Point object represents a location in a two-dimensional coordinate system, where x represents + * the horizontal axis and y represents the vertical axis. + * An observable point is a point that triggers a callback when the point's position is changed. + * + * @class + * @memberof PIXI + * @param cb {Function} callback when changed + * @param scope {Object} owner of callback + * @param [x=0] {number} position of the point on the x axis + * @param [y=0] {number} position of the point on the y axis + */ +function ObservablePoint(cb, scope, x, y) +{ + this._x = x || 0; + this._y = y || 0; + + this.cb = cb; + this.scope = scope; +} + +ObservablePoint.prototype.constructor = ObservablePoint; +module.exports = ObservablePoint; + + + +Object.defineProperties(ObservablePoint.prototype, { + /** + * The position of the displayObject on the x axis relative to the local coordinates of the parent. + * + * @member {number} + * @memberof PIXI.ObservablePoint# + */ + x: { + get: function () + { + return this._x; + }, + set: function (value) + { + if (this._x !== value) { + this._x = value; + this.cb.call(this.scope); + } + } + }, + /** + * The position of the displayObject on the x axis relative to the local coordinates of the parent. + * + * @member {number} + * @memberof PIXI.ObservablePoint# + */ + y: { + get: function () + { + return this._y; + }, + set: function (value) + { + if (this._y !== value) { + this._y = value; + this.cb.call(this.scope); + } + } + } +}); + +/** + * Sets the point to a new x and y position. + * If y is omitted, both x and y will be set to x. + * + * @param [x=0] {number} position of the point on the x axis + * @param [y=0] {number} position of the point on the y axis + */ +ObservablePoint.prototype.set = function (x, y) +{ + var _x = x || 0; + var _y = y || ( (y !== 0) ? _x : 0 ); + if (this._x !== _x || this._y !== _y) + { + this._x = _x; + this._y = _y; + this.cb.call(this.scope); + } +}; + +/** + * Copies the data from another point + * + * @param point {PIXI.Point|{PIXI.ObservablePoint} point to copy from + */ +ObservablePoint.prototype.copy = function (point) +{ + if (this._x !== point.x || this._y !== point.y) + { + this._x = point.x; + this._y = point.y; + this.cb.call(this.scope); + } +}; diff --git a/src/core/math/index.js b/src/core/math/index.js index a43f6e7..8f199d0 100644 --- a/src/core/math/index.js +++ b/src/core/math/index.js @@ -9,13 +9,14 @@ // to avoid circular dependencies and cut down on // internal module requires. - Point: require('./Point'), - Matrix: require('./Matrix'), - GroupD8: require('./GroupD8'), + Point: require('./Point'), + ObservablePoint: require('./ObservablePoint'), + Matrix: require('./Matrix'), + GroupD8: require('./GroupD8'), - Circle: require('./shapes/Circle'), - Ellipse: require('./shapes/Ellipse'), - Polygon: require('./shapes/Polygon'), - Rectangle: require('./shapes/Rectangle'), - RoundedRectangle: require('./shapes/RoundedRectangle') + Circle: require('./shapes/Circle'), + Ellipse: require('./shapes/Ellipse'), + Polygon: require('./shapes/Polygon'), + Rectangle: require('./shapes/Rectangle'), + RoundedRectangle: require('./shapes/RoundedRectangle') }; diff --git a/src/core/const.js b/src/core/const.js index 57d08b9..3f9d5de 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -309,6 +309,12 @@ HIGH: 'highp' }, + TRANSFORM_MODE:{ + STATIC:0, + DYNAMIC:1, + DEFAULT:0 + }, + // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 SPRITE_BATCH_SIZE: 4096, //nice balance between mobile and desktop machines diff --git a/src/core/display/Container.js b/src/core/display/Container.js index 26d9e84..90575c7 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -131,6 +131,9 @@ child.parent = this; + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this.children.push(child); // TODO - lets either do all callbacks or all events.. not both! @@ -366,7 +369,7 @@ return; } - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); //TODO: check render flags, how to process stuff here this.worldAlpha = this.alpha * this.parent.worldAlpha; @@ -468,6 +471,7 @@ var matrixCache = this.transform.worldTransform; this.transform.worldTransform = math.Matrix.IDENTITY; + this.transform._worldID++; for (var i = 0, j = this.children.length; i < j; ++i) { @@ -475,6 +479,7 @@ } this.transform.worldTransform = matrixCache; + this.transform._worldID++; this._currentBounds = null; diff --git a/src/core/display/DisplayObject.js b/src/core/display/DisplayObject.js index 256489f..54a4017 100644 --- a/src/core/display/DisplayObject.js +++ b/src/core/display/DisplayObject.js @@ -1,5 +1,7 @@ var math = require('../math'), EventEmitter = require('eventemitter3'), + CONST = require('../const'), + TransformStatic = require('./TransformStatic'), Transform = require('./Transform'), _tempDisplayObjectParent = new DisplayObject(); @@ -17,12 +19,14 @@ { EventEmitter.call(this); + var TransformClass = CONST.TRANSFORM_MODE.DEFAULT === CONST.TRANSFORM_MODE.STATIC ? TransformStatic : Transform; + //TODO: need to create Transform from factory /** * World transform and local transform of this object. * This will be reworked in v4.1, please do not use it yet unless you know what are you doing! */ - this.transform = new Transform(); + this.transform = new TransformClass(); /** * The opacity of the object. @@ -322,7 +326,7 @@ */ DisplayObject.prototype.updateTransform = function () { - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); // multiply the alphas.. this.worldAlpha = this.alpha * this.parent.worldAlpha; }; diff --git a/src/core/display/ObservablePoint.js b/src/core/display/ObservablePoint.js deleted file mode 100644 index 836fcdd..0000000 --- a/src/core/display/ObservablePoint.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * The Point object represents a location in a two-dimensional coordinate system, where x represents - * the horizontal axis and y represents the vertical axis. - * An observable point is a point that triggers a callback when the point's position is changed. - * - * @class - * @memberof PIXI - * @param cb {Function} callback when changed - * @param scope {Object} owner of callback - * @param [x=0] {number} position of the point on the x axis - * @param [y=0] {number} position of the point on the y axis - */ -function ObservablePoint(cb, scope, x, y) -{ - this._x = x || 0; - this._y = y || 0; - - this.cb = cb; - this.scope = scope; -} - -ObservablePoint.prototype.constructor = ObservablePoint; -module.exports = ObservablePoint; - - - -Object.defineProperties(ObservablePoint.prototype, { - /** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @member {number} - * @memberof PIXI.ObservablePoint# - */ - x: { - get: function () - { - return this._x; - }, - set: function (value) - { - if (this._x !== value) { - this._x = value; - this.cb.call(this.scope); - } - } - }, - /** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @member {number} - * @memberof PIXI.ObservablePoint# - */ - y: { - get: function () - { - return this._y; - }, - set: function (value) - { - if (this._y !== value) { - this._y = value; - this.cb.call(this.scope); - } - } - } -}); - -/** - * Sets the point to a new x and y position. - * If y is omitted, both x and y will be set to x. - * - * @param [x=0] {number} position of the point on the x axis - * @param [y=0] {number} position of the point on the y axis - */ -ObservablePoint.prototype.set = function (x, y) -{ - var _x = x || 0; - var _y = y || ( (y !== 0) ? _x : 0 ); - if (this._x !== _x || this._y !== _y) - { - this._x = _x; - this._y = _y; - this.cb.call(this.scope); - } -}; - -/** - * Copies the data from another point - * - * @param point {PIXI.Point|{PIXI.ObservablePoint} point to copy from - */ -ObservablePoint.prototype.copy = function (point) -{ - if (this._x !== point.x || this._y !== point.y) - { - this._x = point.x; - this._y = point.y; - this.cb.call(this.scope); - } -}; diff --git a/src/core/display/Transform.js b/src/core/display/Transform.js index 2d1e90f..ee8bafb 100644 --- a/src/core/display/Transform.js +++ b/src/core/display/Transform.js @@ -1,5 +1,4 @@ -var math = require('../math'), - ObservablePoint = require('./ObservablePoint'); +var math = require('../math'); /** @@ -35,7 +34,7 @@ this.scale = new math.Point(1,1); - this.skew = new ObservablePoint(this.updateSkew, this, 0,0); + this.skew = new math.ObservablePoint(this.updateSkew, this, 0,0); /** * The pivot point of the displayObject that it rotates around @@ -60,6 +59,8 @@ this._dirty = false; this.updated = true; + + this._worldID = 0; } Transform.prototype.constructor = Transform; @@ -105,15 +106,10 @@ wt.d = lt.c * pt.b + lt.d * pt.d; wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; -}; -Transform.prototype.updateChildTransform = function (childTransform) -{ - childTransform.updateTransform(this); - return childTransform; + this._worldID ++; }; - /** * Decomposes a matrix and sets the transforms properties based on it. * @param {Matrix} diff --git a/src/core/display/TransformStatic.js b/src/core/display/TransformStatic.js index fcab61b..510b716 100644 --- a/src/core/display/TransformStatic.js +++ b/src/core/display/TransformStatic.js @@ -1,5 +1,4 @@ var math = require('../math'); -var ObservablePoint = require('./ObservablePoint'); /** * Transform that takes care about its versions @@ -24,40 +23,62 @@ * * @member {PIXI.ObservablePoint} */ - this.position = new ObservablePoint(this,0.0); + this.position = new math.ObservablePoint(this.onChange, this,0.0); /** * The scale factor of the object. * * @member {PIXI.ObservablePoint} */ - this.scale = new ObservablePoint(this,1,1); + this.scale = new math.ObservablePoint(this.onChange, this,1,1); /** * The pivot point of the displayObject that it rotates around * * @member {PIXI.ObservablePoint} */ - this.pivot = new ObservablePoint(this,0.0); + this.pivot = new math.ObservablePoint(this.onChange, this,0, 0); /** * The skew amount, on the x and y axis. * * @member {PIXI.ObservablePoint} */ - this.skew = new ObservablePoint(this,0.0); + this.skew = new math.ObservablePoint(this.updateSkew, this,0, 0); this._rotation = 0; + this._sr = Math.sin(0); this._cr = Math.cos(0); + this._cy = Math.cos(0);//skewY); + this._sy = Math.sin(0);//skewY); + this._nsx = Math.sin(0);//skewX); + this._cx = Math.cos(0);//skewX); - this._dirtyLocal = 0; - this._versionLocal = 0; - this._versionGlobal = 0; + + this._localID = 0; + this._currentLocalID = 0; + this._parentID = 0; + this._worldID = 0; } TransformStatic.prototype.constructor = TransformStatic; +TransformStatic.prototype.onChange = function () +{ + this._localID ++; +}; + +TransformStatic.prototype.updateSkew = function () +{ + this._cy = Math.cos(this.skew.y); + this._sy = Math.sin(this.skew.y); + this._nsx = Math.sin(this.skew.x); + this._cx = Math.cos(this.skew.x); + + this._localID ++; +}; + /** * Updates the values of the object and applies the parent's transform. * @param parentTransform {PIXI.Transform} The transform of the parent of this object @@ -69,35 +90,57 @@ var wt = this.worldTransform; var lt = this.localTransform; - if(this._dirtyLocal !== this._versionLocal) + if(this._localID !== this._currentLocalID) { // get the matrix values of the displayobject based on its transform properties.. - lt.a = this._cr * this.scale._x; - lt.b = this._sr * this.scale._x; - lt.c = -this._sr * this.scale._y; - lt.d = this._cr * this.scale._y; + var a,b,c,d; + + a = this._cr * this.scale.x; + b = this._sr * this.scale.x; + c = -this._sr * this.scale.y; + d = this._cr * this.scale.y; + + lt.a = this._cy * a + this._sy * c; + lt.b = this._cy * b + this._sy * d; + lt.c = this._nsx * a + this._cx * c; + lt.d = this._nsx * b + this._cx * d; + lt.tx = this.position._x - (this.pivot._x * lt.a + this.pivot._y * lt.c); lt.ty = this.position._y - (this.pivot._x * lt.b + this.pivot._y * lt.d); - this._dirtyLocal = this._versionLocal; + this._currentLocalID = this._localID; + + // force an update.. + this._parentID = -1; } - // concat the parent matrix with the objects transform. - wt.a = lt.a * pt.a + lt.b * pt.c; - wt.b = lt.a * pt.b + lt.b * pt.d; - wt.c = lt.c * pt.a + lt.d * pt.c; - wt.d = lt.c * pt.b + lt.d * pt.d; - wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; - wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; - this._versionGlobal++; - this.updated = true; + if(this._parentID !== parentTransform._worldID) + { + // concat the parent matrix with the objects transform. + wt.a = lt.a * pt.a + lt.b * pt.c; + wt.b = lt.a * pt.b + lt.b * pt.d; + wt.c = lt.c * pt.a + lt.d * pt.c; + wt.d = lt.c * pt.b + lt.d * pt.d; + wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; + wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; + + this._parentID = parentTransform._worldID; + + // update the id of the transform.. + this._worldID ++; + } }; -TransformStatic.prototype.updateChildTransform = function (childTransform) +/** + * Decomposes a matrix and sets the transforms properties based on it. + * @param {Matrix} + */ +TransformStatic.prototype.setFromMatrix = function (matrix) { - childTransform.updateTransform(this); - return childTransform; + matrix.decompose(this); }; + + Object.defineProperties(TransformStatic.prototype, { /** * The rotation of the object in radians. @@ -112,6 +155,7 @@ this._rotation = value; this._sr = Math.sin(value); this._cr = Math.cos(value); + this._localID ++; } } }); diff --git a/src/core/math/ObservablePoint.js b/src/core/math/ObservablePoint.js new file mode 100644 index 0000000..836fcdd --- /dev/null +++ b/src/core/math/ObservablePoint.js @@ -0,0 +1,100 @@ +/** + * The Point object represents a location in a two-dimensional coordinate system, where x represents + * the horizontal axis and y represents the vertical axis. + * An observable point is a point that triggers a callback when the point's position is changed. + * + * @class + * @memberof PIXI + * @param cb {Function} callback when changed + * @param scope {Object} owner of callback + * @param [x=0] {number} position of the point on the x axis + * @param [y=0] {number} position of the point on the y axis + */ +function ObservablePoint(cb, scope, x, y) +{ + this._x = x || 0; + this._y = y || 0; + + this.cb = cb; + this.scope = scope; +} + +ObservablePoint.prototype.constructor = ObservablePoint; +module.exports = ObservablePoint; + + + +Object.defineProperties(ObservablePoint.prototype, { + /** + * The position of the displayObject on the x axis relative to the local coordinates of the parent. + * + * @member {number} + * @memberof PIXI.ObservablePoint# + */ + x: { + get: function () + { + return this._x; + }, + set: function (value) + { + if (this._x !== value) { + this._x = value; + this.cb.call(this.scope); + } + } + }, + /** + * The position of the displayObject on the x axis relative to the local coordinates of the parent. + * + * @member {number} + * @memberof PIXI.ObservablePoint# + */ + y: { + get: function () + { + return this._y; + }, + set: function (value) + { + if (this._y !== value) { + this._y = value; + this.cb.call(this.scope); + } + } + } +}); + +/** + * Sets the point to a new x and y position. + * If y is omitted, both x and y will be set to x. + * + * @param [x=0] {number} position of the point on the x axis + * @param [y=0] {number} position of the point on the y axis + */ +ObservablePoint.prototype.set = function (x, y) +{ + var _x = x || 0; + var _y = y || ( (y !== 0) ? _x : 0 ); + if (this._x !== _x || this._y !== _y) + { + this._x = _x; + this._y = _y; + this.cb.call(this.scope); + } +}; + +/** + * Copies the data from another point + * + * @param point {PIXI.Point|{PIXI.ObservablePoint} point to copy from + */ +ObservablePoint.prototype.copy = function (point) +{ + if (this._x !== point.x || this._y !== point.y) + { + this._x = point.x; + this._y = point.y; + this.cb.call(this.scope); + } +}; diff --git a/src/core/math/index.js b/src/core/math/index.js index a43f6e7..8f199d0 100644 --- a/src/core/math/index.js +++ b/src/core/math/index.js @@ -9,13 +9,14 @@ // to avoid circular dependencies and cut down on // internal module requires. - Point: require('./Point'), - Matrix: require('./Matrix'), - GroupD8: require('./GroupD8'), + Point: require('./Point'), + ObservablePoint: require('./ObservablePoint'), + Matrix: require('./Matrix'), + GroupD8: require('./GroupD8'), - Circle: require('./shapes/Circle'), - Ellipse: require('./shapes/Ellipse'), - Polygon: require('./shapes/Polygon'), - Rectangle: require('./shapes/Rectangle'), - RoundedRectangle: require('./shapes/RoundedRectangle') + Circle: require('./shapes/Circle'), + Ellipse: require('./shapes/Ellipse'), + Polygon: require('./shapes/Polygon'), + Rectangle: require('./shapes/Rectangle'), + RoundedRectangle: require('./shapes/RoundedRectangle') }; diff --git a/src/core/sprites/Sprite.js b/src/core/sprites/Sprite.js index b4350f7..6a60a81 100644 --- a/src/core/sprites/Sprite.js +++ b/src/core/sprites/Sprite.js @@ -31,7 +31,7 @@ * * @member {PIXI.Point} */ - this.anchor = new math.Point(); + this.anchor = new math.ObservablePoint(this.onAnchorUpdate, this); /** * The texture that the sprite is using @@ -91,8 +91,9 @@ // call texture setter this.texture = texture || Texture.EMPTY; - this.textureDirty = true; this.vertexData = new Float32Array(16); + this._transformID = -1; + this._textureID = -1; } // constructor @@ -160,7 +161,7 @@ this._texture = value; this.cachedTint = 0xFFFFFF; - this.textureDirty = true; + this._textureID = -1; if (value) { @@ -185,7 +186,7 @@ */ Sprite.prototype._onTextureUpdate = function () { - this.textureDirty = true; + this._textureID = -1; // so if _width is 0 then width was not set.. if (this._width) @@ -199,11 +200,26 @@ } }; +Sprite.prototype.onAnchorUpdate = function() +{ + this._transformID = -1; +}; + /** * calculates worldTransform * vertices, store it in vertexData */ Sprite.prototype.calculateVertices = function () { + if(this._transformID === this.transform._worldID && this._textureID === this._texture._updateID) + { + return; + } + + this._transformID = this.transform._worldID; + this._textureID = this._texture._updateID; + + // set the vertex data + var texture = this._texture, wt = this.transform.worldTransform, a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty, @@ -307,12 +323,7 @@ */ Sprite.prototype._renderWebGL = function (renderer) { - if(this.transform.updated || this.textureDirty) - { - this.textureDirty = false; - // set the vertex data - this.calculateVertices(); - } + this.calculateVertices(); renderer.setObjectRenderer(renderer.plugins.sprite); renderer.plugins.sprite.render(this); @@ -340,14 +351,11 @@ //TODO lookinto caching.. if(!this._currentBounds) { - // if(this.vertexDirty) - { - this.vertexDirty = false; + // set the vertex data + this.calculateVertices(); - // set the vertex data - this.calculateBoundsVertices(); - - } + // set the vertex data + this.calculateBoundsVertices(); var minX, maxX, minY, maxY, w0, w1, h0, h1, diff --git a/src/core/const.js b/src/core/const.js index 57d08b9..3f9d5de 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -309,6 +309,12 @@ HIGH: 'highp' }, + TRANSFORM_MODE:{ + STATIC:0, + DYNAMIC:1, + DEFAULT:0 + }, + // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 SPRITE_BATCH_SIZE: 4096, //nice balance between mobile and desktop machines diff --git a/src/core/display/Container.js b/src/core/display/Container.js index 26d9e84..90575c7 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -131,6 +131,9 @@ child.parent = this; + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this.children.push(child); // TODO - lets either do all callbacks or all events.. not both! @@ -366,7 +369,7 @@ return; } - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); //TODO: check render flags, how to process stuff here this.worldAlpha = this.alpha * this.parent.worldAlpha; @@ -468,6 +471,7 @@ var matrixCache = this.transform.worldTransform; this.transform.worldTransform = math.Matrix.IDENTITY; + this.transform._worldID++; for (var i = 0, j = this.children.length; i < j; ++i) { @@ -475,6 +479,7 @@ } this.transform.worldTransform = matrixCache; + this.transform._worldID++; this._currentBounds = null; diff --git a/src/core/display/DisplayObject.js b/src/core/display/DisplayObject.js index 256489f..54a4017 100644 --- a/src/core/display/DisplayObject.js +++ b/src/core/display/DisplayObject.js @@ -1,5 +1,7 @@ var math = require('../math'), EventEmitter = require('eventemitter3'), + CONST = require('../const'), + TransformStatic = require('./TransformStatic'), Transform = require('./Transform'), _tempDisplayObjectParent = new DisplayObject(); @@ -17,12 +19,14 @@ { EventEmitter.call(this); + var TransformClass = CONST.TRANSFORM_MODE.DEFAULT === CONST.TRANSFORM_MODE.STATIC ? TransformStatic : Transform; + //TODO: need to create Transform from factory /** * World transform and local transform of this object. * This will be reworked in v4.1, please do not use it yet unless you know what are you doing! */ - this.transform = new Transform(); + this.transform = new TransformClass(); /** * The opacity of the object. @@ -322,7 +326,7 @@ */ DisplayObject.prototype.updateTransform = function () { - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); // multiply the alphas.. this.worldAlpha = this.alpha * this.parent.worldAlpha; }; diff --git a/src/core/display/ObservablePoint.js b/src/core/display/ObservablePoint.js deleted file mode 100644 index 836fcdd..0000000 --- a/src/core/display/ObservablePoint.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * The Point object represents a location in a two-dimensional coordinate system, where x represents - * the horizontal axis and y represents the vertical axis. - * An observable point is a point that triggers a callback when the point's position is changed. - * - * @class - * @memberof PIXI - * @param cb {Function} callback when changed - * @param scope {Object} owner of callback - * @param [x=0] {number} position of the point on the x axis - * @param [y=0] {number} position of the point on the y axis - */ -function ObservablePoint(cb, scope, x, y) -{ - this._x = x || 0; - this._y = y || 0; - - this.cb = cb; - this.scope = scope; -} - -ObservablePoint.prototype.constructor = ObservablePoint; -module.exports = ObservablePoint; - - - -Object.defineProperties(ObservablePoint.prototype, { - /** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @member {number} - * @memberof PIXI.ObservablePoint# - */ - x: { - get: function () - { - return this._x; - }, - set: function (value) - { - if (this._x !== value) { - this._x = value; - this.cb.call(this.scope); - } - } - }, - /** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @member {number} - * @memberof PIXI.ObservablePoint# - */ - y: { - get: function () - { - return this._y; - }, - set: function (value) - { - if (this._y !== value) { - this._y = value; - this.cb.call(this.scope); - } - } - } -}); - -/** - * Sets the point to a new x and y position. - * If y is omitted, both x and y will be set to x. - * - * @param [x=0] {number} position of the point on the x axis - * @param [y=0] {number} position of the point on the y axis - */ -ObservablePoint.prototype.set = function (x, y) -{ - var _x = x || 0; - var _y = y || ( (y !== 0) ? _x : 0 ); - if (this._x !== _x || this._y !== _y) - { - this._x = _x; - this._y = _y; - this.cb.call(this.scope); - } -}; - -/** - * Copies the data from another point - * - * @param point {PIXI.Point|{PIXI.ObservablePoint} point to copy from - */ -ObservablePoint.prototype.copy = function (point) -{ - if (this._x !== point.x || this._y !== point.y) - { - this._x = point.x; - this._y = point.y; - this.cb.call(this.scope); - } -}; diff --git a/src/core/display/Transform.js b/src/core/display/Transform.js index 2d1e90f..ee8bafb 100644 --- a/src/core/display/Transform.js +++ b/src/core/display/Transform.js @@ -1,5 +1,4 @@ -var math = require('../math'), - ObservablePoint = require('./ObservablePoint'); +var math = require('../math'); /** @@ -35,7 +34,7 @@ this.scale = new math.Point(1,1); - this.skew = new ObservablePoint(this.updateSkew, this, 0,0); + this.skew = new math.ObservablePoint(this.updateSkew, this, 0,0); /** * The pivot point of the displayObject that it rotates around @@ -60,6 +59,8 @@ this._dirty = false; this.updated = true; + + this._worldID = 0; } Transform.prototype.constructor = Transform; @@ -105,15 +106,10 @@ wt.d = lt.c * pt.b + lt.d * pt.d; wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; -}; -Transform.prototype.updateChildTransform = function (childTransform) -{ - childTransform.updateTransform(this); - return childTransform; + this._worldID ++; }; - /** * Decomposes a matrix and sets the transforms properties based on it. * @param {Matrix} diff --git a/src/core/display/TransformStatic.js b/src/core/display/TransformStatic.js index fcab61b..510b716 100644 --- a/src/core/display/TransformStatic.js +++ b/src/core/display/TransformStatic.js @@ -1,5 +1,4 @@ var math = require('../math'); -var ObservablePoint = require('./ObservablePoint'); /** * Transform that takes care about its versions @@ -24,40 +23,62 @@ * * @member {PIXI.ObservablePoint} */ - this.position = new ObservablePoint(this,0.0); + this.position = new math.ObservablePoint(this.onChange, this,0.0); /** * The scale factor of the object. * * @member {PIXI.ObservablePoint} */ - this.scale = new ObservablePoint(this,1,1); + this.scale = new math.ObservablePoint(this.onChange, this,1,1); /** * The pivot point of the displayObject that it rotates around * * @member {PIXI.ObservablePoint} */ - this.pivot = new ObservablePoint(this,0.0); + this.pivot = new math.ObservablePoint(this.onChange, this,0, 0); /** * The skew amount, on the x and y axis. * * @member {PIXI.ObservablePoint} */ - this.skew = new ObservablePoint(this,0.0); + this.skew = new math.ObservablePoint(this.updateSkew, this,0, 0); this._rotation = 0; + this._sr = Math.sin(0); this._cr = Math.cos(0); + this._cy = Math.cos(0);//skewY); + this._sy = Math.sin(0);//skewY); + this._nsx = Math.sin(0);//skewX); + this._cx = Math.cos(0);//skewX); - this._dirtyLocal = 0; - this._versionLocal = 0; - this._versionGlobal = 0; + + this._localID = 0; + this._currentLocalID = 0; + this._parentID = 0; + this._worldID = 0; } TransformStatic.prototype.constructor = TransformStatic; +TransformStatic.prototype.onChange = function () +{ + this._localID ++; +}; + +TransformStatic.prototype.updateSkew = function () +{ + this._cy = Math.cos(this.skew.y); + this._sy = Math.sin(this.skew.y); + this._nsx = Math.sin(this.skew.x); + this._cx = Math.cos(this.skew.x); + + this._localID ++; +}; + /** * Updates the values of the object and applies the parent's transform. * @param parentTransform {PIXI.Transform} The transform of the parent of this object @@ -69,35 +90,57 @@ var wt = this.worldTransform; var lt = this.localTransform; - if(this._dirtyLocal !== this._versionLocal) + if(this._localID !== this._currentLocalID) { // get the matrix values of the displayobject based on its transform properties.. - lt.a = this._cr * this.scale._x; - lt.b = this._sr * this.scale._x; - lt.c = -this._sr * this.scale._y; - lt.d = this._cr * this.scale._y; + var a,b,c,d; + + a = this._cr * this.scale.x; + b = this._sr * this.scale.x; + c = -this._sr * this.scale.y; + d = this._cr * this.scale.y; + + lt.a = this._cy * a + this._sy * c; + lt.b = this._cy * b + this._sy * d; + lt.c = this._nsx * a + this._cx * c; + lt.d = this._nsx * b + this._cx * d; + lt.tx = this.position._x - (this.pivot._x * lt.a + this.pivot._y * lt.c); lt.ty = this.position._y - (this.pivot._x * lt.b + this.pivot._y * lt.d); - this._dirtyLocal = this._versionLocal; + this._currentLocalID = this._localID; + + // force an update.. + this._parentID = -1; } - // concat the parent matrix with the objects transform. - wt.a = lt.a * pt.a + lt.b * pt.c; - wt.b = lt.a * pt.b + lt.b * pt.d; - wt.c = lt.c * pt.a + lt.d * pt.c; - wt.d = lt.c * pt.b + lt.d * pt.d; - wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; - wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; - this._versionGlobal++; - this.updated = true; + if(this._parentID !== parentTransform._worldID) + { + // concat the parent matrix with the objects transform. + wt.a = lt.a * pt.a + lt.b * pt.c; + wt.b = lt.a * pt.b + lt.b * pt.d; + wt.c = lt.c * pt.a + lt.d * pt.c; + wt.d = lt.c * pt.b + lt.d * pt.d; + wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; + wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; + + this._parentID = parentTransform._worldID; + + // update the id of the transform.. + this._worldID ++; + } }; -TransformStatic.prototype.updateChildTransform = function (childTransform) +/** + * Decomposes a matrix and sets the transforms properties based on it. + * @param {Matrix} + */ +TransformStatic.prototype.setFromMatrix = function (matrix) { - childTransform.updateTransform(this); - return childTransform; + matrix.decompose(this); }; + + Object.defineProperties(TransformStatic.prototype, { /** * The rotation of the object in radians. @@ -112,6 +155,7 @@ this._rotation = value; this._sr = Math.sin(value); this._cr = Math.cos(value); + this._localID ++; } } }); diff --git a/src/core/math/ObservablePoint.js b/src/core/math/ObservablePoint.js new file mode 100644 index 0000000..836fcdd --- /dev/null +++ b/src/core/math/ObservablePoint.js @@ -0,0 +1,100 @@ +/** + * The Point object represents a location in a two-dimensional coordinate system, where x represents + * the horizontal axis and y represents the vertical axis. + * An observable point is a point that triggers a callback when the point's position is changed. + * + * @class + * @memberof PIXI + * @param cb {Function} callback when changed + * @param scope {Object} owner of callback + * @param [x=0] {number} position of the point on the x axis + * @param [y=0] {number} position of the point on the y axis + */ +function ObservablePoint(cb, scope, x, y) +{ + this._x = x || 0; + this._y = y || 0; + + this.cb = cb; + this.scope = scope; +} + +ObservablePoint.prototype.constructor = ObservablePoint; +module.exports = ObservablePoint; + + + +Object.defineProperties(ObservablePoint.prototype, { + /** + * The position of the displayObject on the x axis relative to the local coordinates of the parent. + * + * @member {number} + * @memberof PIXI.ObservablePoint# + */ + x: { + get: function () + { + return this._x; + }, + set: function (value) + { + if (this._x !== value) { + this._x = value; + this.cb.call(this.scope); + } + } + }, + /** + * The position of the displayObject on the x axis relative to the local coordinates of the parent. + * + * @member {number} + * @memberof PIXI.ObservablePoint# + */ + y: { + get: function () + { + return this._y; + }, + set: function (value) + { + if (this._y !== value) { + this._y = value; + this.cb.call(this.scope); + } + } + } +}); + +/** + * Sets the point to a new x and y position. + * If y is omitted, both x and y will be set to x. + * + * @param [x=0] {number} position of the point on the x axis + * @param [y=0] {number} position of the point on the y axis + */ +ObservablePoint.prototype.set = function (x, y) +{ + var _x = x || 0; + var _y = y || ( (y !== 0) ? _x : 0 ); + if (this._x !== _x || this._y !== _y) + { + this._x = _x; + this._y = _y; + this.cb.call(this.scope); + } +}; + +/** + * Copies the data from another point + * + * @param point {PIXI.Point|{PIXI.ObservablePoint} point to copy from + */ +ObservablePoint.prototype.copy = function (point) +{ + if (this._x !== point.x || this._y !== point.y) + { + this._x = point.x; + this._y = point.y; + this.cb.call(this.scope); + } +}; diff --git a/src/core/math/index.js b/src/core/math/index.js index a43f6e7..8f199d0 100644 --- a/src/core/math/index.js +++ b/src/core/math/index.js @@ -9,13 +9,14 @@ // to avoid circular dependencies and cut down on // internal module requires. - Point: require('./Point'), - Matrix: require('./Matrix'), - GroupD8: require('./GroupD8'), + Point: require('./Point'), + ObservablePoint: require('./ObservablePoint'), + Matrix: require('./Matrix'), + GroupD8: require('./GroupD8'), - Circle: require('./shapes/Circle'), - Ellipse: require('./shapes/Ellipse'), - Polygon: require('./shapes/Polygon'), - Rectangle: require('./shapes/Rectangle'), - RoundedRectangle: require('./shapes/RoundedRectangle') + Circle: require('./shapes/Circle'), + Ellipse: require('./shapes/Ellipse'), + Polygon: require('./shapes/Polygon'), + Rectangle: require('./shapes/Rectangle'), + RoundedRectangle: require('./shapes/RoundedRectangle') }; diff --git a/src/core/sprites/Sprite.js b/src/core/sprites/Sprite.js index b4350f7..6a60a81 100644 --- a/src/core/sprites/Sprite.js +++ b/src/core/sprites/Sprite.js @@ -31,7 +31,7 @@ * * @member {PIXI.Point} */ - this.anchor = new math.Point(); + this.anchor = new math.ObservablePoint(this.onAnchorUpdate, this); /** * The texture that the sprite is using @@ -91,8 +91,9 @@ // call texture setter this.texture = texture || Texture.EMPTY; - this.textureDirty = true; this.vertexData = new Float32Array(16); + this._transformID = -1; + this._textureID = -1; } // constructor @@ -160,7 +161,7 @@ this._texture = value; this.cachedTint = 0xFFFFFF; - this.textureDirty = true; + this._textureID = -1; if (value) { @@ -185,7 +186,7 @@ */ Sprite.prototype._onTextureUpdate = function () { - this.textureDirty = true; + this._textureID = -1; // so if _width is 0 then width was not set.. if (this._width) @@ -199,11 +200,26 @@ } }; +Sprite.prototype.onAnchorUpdate = function() +{ + this._transformID = -1; +}; + /** * calculates worldTransform * vertices, store it in vertexData */ Sprite.prototype.calculateVertices = function () { + if(this._transformID === this.transform._worldID && this._textureID === this._texture._updateID) + { + return; + } + + this._transformID = this.transform._worldID; + this._textureID = this._texture._updateID; + + // set the vertex data + var texture = this._texture, wt = this.transform.worldTransform, a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty, @@ -307,12 +323,7 @@ */ Sprite.prototype._renderWebGL = function (renderer) { - if(this.transform.updated || this.textureDirty) - { - this.textureDirty = false; - // set the vertex data - this.calculateVertices(); - } + this.calculateVertices(); renderer.setObjectRenderer(renderer.plugins.sprite); renderer.plugins.sprite.render(this); @@ -340,14 +351,11 @@ //TODO lookinto caching.. if(!this._currentBounds) { - // if(this.vertexDirty) - { - this.vertexDirty = false; + // set the vertex data + this.calculateVertices(); - // set the vertex data - this.calculateBoundsVertices(); - - } + // set the vertex data + this.calculateBoundsVertices(); var minX, maxX, minY, maxY, w0, w1, h0, h1, diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index e26e780..74c2699 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -132,6 +132,9 @@ * @memberof PIXI.Texture# * @protected */ + + + this._updateID = 0; } Texture.prototype = Object.create(EventEmitter.prototype); @@ -238,6 +241,8 @@ */ Texture.prototype.onBaseTextureLoaded = function (baseTexture) { + this._updateID++; + // TODO this code looks confusing.. boo to abusing getters and setterss! if (this.noFrame) { @@ -250,6 +255,7 @@ this.baseTexture.on('update', this.onBaseTextureUpdated, this); this.emit('update', this); + }; /** @@ -259,6 +265,8 @@ */ Texture.prototype.onBaseTextureUpdated = function (baseTexture) { + this._updateID++; + this._frame.width = baseTexture.width; this._frame.height = baseTexture.height; @@ -327,6 +335,8 @@ } this._uvs.set(this._frame, this.baseTexture, this.rotate); + + this._updateID++; }; /** diff --git a/src/core/const.js b/src/core/const.js index 57d08b9..3f9d5de 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -309,6 +309,12 @@ HIGH: 'highp' }, + TRANSFORM_MODE:{ + STATIC:0, + DYNAMIC:1, + DEFAULT:0 + }, + // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 SPRITE_BATCH_SIZE: 4096, //nice balance between mobile and desktop machines diff --git a/src/core/display/Container.js b/src/core/display/Container.js index 26d9e84..90575c7 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -131,6 +131,9 @@ child.parent = this; + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this.children.push(child); // TODO - lets either do all callbacks or all events.. not both! @@ -366,7 +369,7 @@ return; } - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); //TODO: check render flags, how to process stuff here this.worldAlpha = this.alpha * this.parent.worldAlpha; @@ -468,6 +471,7 @@ var matrixCache = this.transform.worldTransform; this.transform.worldTransform = math.Matrix.IDENTITY; + this.transform._worldID++; for (var i = 0, j = this.children.length; i < j; ++i) { @@ -475,6 +479,7 @@ } this.transform.worldTransform = matrixCache; + this.transform._worldID++; this._currentBounds = null; diff --git a/src/core/display/DisplayObject.js b/src/core/display/DisplayObject.js index 256489f..54a4017 100644 --- a/src/core/display/DisplayObject.js +++ b/src/core/display/DisplayObject.js @@ -1,5 +1,7 @@ var math = require('../math'), EventEmitter = require('eventemitter3'), + CONST = require('../const'), + TransformStatic = require('./TransformStatic'), Transform = require('./Transform'), _tempDisplayObjectParent = new DisplayObject(); @@ -17,12 +19,14 @@ { EventEmitter.call(this); + var TransformClass = CONST.TRANSFORM_MODE.DEFAULT === CONST.TRANSFORM_MODE.STATIC ? TransformStatic : Transform; + //TODO: need to create Transform from factory /** * World transform and local transform of this object. * This will be reworked in v4.1, please do not use it yet unless you know what are you doing! */ - this.transform = new Transform(); + this.transform = new TransformClass(); /** * The opacity of the object. @@ -322,7 +326,7 @@ */ DisplayObject.prototype.updateTransform = function () { - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); // multiply the alphas.. this.worldAlpha = this.alpha * this.parent.worldAlpha; }; diff --git a/src/core/display/ObservablePoint.js b/src/core/display/ObservablePoint.js deleted file mode 100644 index 836fcdd..0000000 --- a/src/core/display/ObservablePoint.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * The Point object represents a location in a two-dimensional coordinate system, where x represents - * the horizontal axis and y represents the vertical axis. - * An observable point is a point that triggers a callback when the point's position is changed. - * - * @class - * @memberof PIXI - * @param cb {Function} callback when changed - * @param scope {Object} owner of callback - * @param [x=0] {number} position of the point on the x axis - * @param [y=0] {number} position of the point on the y axis - */ -function ObservablePoint(cb, scope, x, y) -{ - this._x = x || 0; - this._y = y || 0; - - this.cb = cb; - this.scope = scope; -} - -ObservablePoint.prototype.constructor = ObservablePoint; -module.exports = ObservablePoint; - - - -Object.defineProperties(ObservablePoint.prototype, { - /** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @member {number} - * @memberof PIXI.ObservablePoint# - */ - x: { - get: function () - { - return this._x; - }, - set: function (value) - { - if (this._x !== value) { - this._x = value; - this.cb.call(this.scope); - } - } - }, - /** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @member {number} - * @memberof PIXI.ObservablePoint# - */ - y: { - get: function () - { - return this._y; - }, - set: function (value) - { - if (this._y !== value) { - this._y = value; - this.cb.call(this.scope); - } - } - } -}); - -/** - * Sets the point to a new x and y position. - * If y is omitted, both x and y will be set to x. - * - * @param [x=0] {number} position of the point on the x axis - * @param [y=0] {number} position of the point on the y axis - */ -ObservablePoint.prototype.set = function (x, y) -{ - var _x = x || 0; - var _y = y || ( (y !== 0) ? _x : 0 ); - if (this._x !== _x || this._y !== _y) - { - this._x = _x; - this._y = _y; - this.cb.call(this.scope); - } -}; - -/** - * Copies the data from another point - * - * @param point {PIXI.Point|{PIXI.ObservablePoint} point to copy from - */ -ObservablePoint.prototype.copy = function (point) -{ - if (this._x !== point.x || this._y !== point.y) - { - this._x = point.x; - this._y = point.y; - this.cb.call(this.scope); - } -}; diff --git a/src/core/display/Transform.js b/src/core/display/Transform.js index 2d1e90f..ee8bafb 100644 --- a/src/core/display/Transform.js +++ b/src/core/display/Transform.js @@ -1,5 +1,4 @@ -var math = require('../math'), - ObservablePoint = require('./ObservablePoint'); +var math = require('../math'); /** @@ -35,7 +34,7 @@ this.scale = new math.Point(1,1); - this.skew = new ObservablePoint(this.updateSkew, this, 0,0); + this.skew = new math.ObservablePoint(this.updateSkew, this, 0,0); /** * The pivot point of the displayObject that it rotates around @@ -60,6 +59,8 @@ this._dirty = false; this.updated = true; + + this._worldID = 0; } Transform.prototype.constructor = Transform; @@ -105,15 +106,10 @@ wt.d = lt.c * pt.b + lt.d * pt.d; wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; -}; -Transform.prototype.updateChildTransform = function (childTransform) -{ - childTransform.updateTransform(this); - return childTransform; + this._worldID ++; }; - /** * Decomposes a matrix and sets the transforms properties based on it. * @param {Matrix} diff --git a/src/core/display/TransformStatic.js b/src/core/display/TransformStatic.js index fcab61b..510b716 100644 --- a/src/core/display/TransformStatic.js +++ b/src/core/display/TransformStatic.js @@ -1,5 +1,4 @@ var math = require('../math'); -var ObservablePoint = require('./ObservablePoint'); /** * Transform that takes care about its versions @@ -24,40 +23,62 @@ * * @member {PIXI.ObservablePoint} */ - this.position = new ObservablePoint(this,0.0); + this.position = new math.ObservablePoint(this.onChange, this,0.0); /** * The scale factor of the object. * * @member {PIXI.ObservablePoint} */ - this.scale = new ObservablePoint(this,1,1); + this.scale = new math.ObservablePoint(this.onChange, this,1,1); /** * The pivot point of the displayObject that it rotates around * * @member {PIXI.ObservablePoint} */ - this.pivot = new ObservablePoint(this,0.0); + this.pivot = new math.ObservablePoint(this.onChange, this,0, 0); /** * The skew amount, on the x and y axis. * * @member {PIXI.ObservablePoint} */ - this.skew = new ObservablePoint(this,0.0); + this.skew = new math.ObservablePoint(this.updateSkew, this,0, 0); this._rotation = 0; + this._sr = Math.sin(0); this._cr = Math.cos(0); + this._cy = Math.cos(0);//skewY); + this._sy = Math.sin(0);//skewY); + this._nsx = Math.sin(0);//skewX); + this._cx = Math.cos(0);//skewX); - this._dirtyLocal = 0; - this._versionLocal = 0; - this._versionGlobal = 0; + + this._localID = 0; + this._currentLocalID = 0; + this._parentID = 0; + this._worldID = 0; } TransformStatic.prototype.constructor = TransformStatic; +TransformStatic.prototype.onChange = function () +{ + this._localID ++; +}; + +TransformStatic.prototype.updateSkew = function () +{ + this._cy = Math.cos(this.skew.y); + this._sy = Math.sin(this.skew.y); + this._nsx = Math.sin(this.skew.x); + this._cx = Math.cos(this.skew.x); + + this._localID ++; +}; + /** * Updates the values of the object and applies the parent's transform. * @param parentTransform {PIXI.Transform} The transform of the parent of this object @@ -69,35 +90,57 @@ var wt = this.worldTransform; var lt = this.localTransform; - if(this._dirtyLocal !== this._versionLocal) + if(this._localID !== this._currentLocalID) { // get the matrix values of the displayobject based on its transform properties.. - lt.a = this._cr * this.scale._x; - lt.b = this._sr * this.scale._x; - lt.c = -this._sr * this.scale._y; - lt.d = this._cr * this.scale._y; + var a,b,c,d; + + a = this._cr * this.scale.x; + b = this._sr * this.scale.x; + c = -this._sr * this.scale.y; + d = this._cr * this.scale.y; + + lt.a = this._cy * a + this._sy * c; + lt.b = this._cy * b + this._sy * d; + lt.c = this._nsx * a + this._cx * c; + lt.d = this._nsx * b + this._cx * d; + lt.tx = this.position._x - (this.pivot._x * lt.a + this.pivot._y * lt.c); lt.ty = this.position._y - (this.pivot._x * lt.b + this.pivot._y * lt.d); - this._dirtyLocal = this._versionLocal; + this._currentLocalID = this._localID; + + // force an update.. + this._parentID = -1; } - // concat the parent matrix with the objects transform. - wt.a = lt.a * pt.a + lt.b * pt.c; - wt.b = lt.a * pt.b + lt.b * pt.d; - wt.c = lt.c * pt.a + lt.d * pt.c; - wt.d = lt.c * pt.b + lt.d * pt.d; - wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; - wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; - this._versionGlobal++; - this.updated = true; + if(this._parentID !== parentTransform._worldID) + { + // concat the parent matrix with the objects transform. + wt.a = lt.a * pt.a + lt.b * pt.c; + wt.b = lt.a * pt.b + lt.b * pt.d; + wt.c = lt.c * pt.a + lt.d * pt.c; + wt.d = lt.c * pt.b + lt.d * pt.d; + wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; + wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; + + this._parentID = parentTransform._worldID; + + // update the id of the transform.. + this._worldID ++; + } }; -TransformStatic.prototype.updateChildTransform = function (childTransform) +/** + * Decomposes a matrix and sets the transforms properties based on it. + * @param {Matrix} + */ +TransformStatic.prototype.setFromMatrix = function (matrix) { - childTransform.updateTransform(this); - return childTransform; + matrix.decompose(this); }; + + Object.defineProperties(TransformStatic.prototype, { /** * The rotation of the object in radians. @@ -112,6 +155,7 @@ this._rotation = value; this._sr = Math.sin(value); this._cr = Math.cos(value); + this._localID ++; } } }); diff --git a/src/core/math/ObservablePoint.js b/src/core/math/ObservablePoint.js new file mode 100644 index 0000000..836fcdd --- /dev/null +++ b/src/core/math/ObservablePoint.js @@ -0,0 +1,100 @@ +/** + * The Point object represents a location in a two-dimensional coordinate system, where x represents + * the horizontal axis and y represents the vertical axis. + * An observable point is a point that triggers a callback when the point's position is changed. + * + * @class + * @memberof PIXI + * @param cb {Function} callback when changed + * @param scope {Object} owner of callback + * @param [x=0] {number} position of the point on the x axis + * @param [y=0] {number} position of the point on the y axis + */ +function ObservablePoint(cb, scope, x, y) +{ + this._x = x || 0; + this._y = y || 0; + + this.cb = cb; + this.scope = scope; +} + +ObservablePoint.prototype.constructor = ObservablePoint; +module.exports = ObservablePoint; + + + +Object.defineProperties(ObservablePoint.prototype, { + /** + * The position of the displayObject on the x axis relative to the local coordinates of the parent. + * + * @member {number} + * @memberof PIXI.ObservablePoint# + */ + x: { + get: function () + { + return this._x; + }, + set: function (value) + { + if (this._x !== value) { + this._x = value; + this.cb.call(this.scope); + } + } + }, + /** + * The position of the displayObject on the x axis relative to the local coordinates of the parent. + * + * @member {number} + * @memberof PIXI.ObservablePoint# + */ + y: { + get: function () + { + return this._y; + }, + set: function (value) + { + if (this._y !== value) { + this._y = value; + this.cb.call(this.scope); + } + } + } +}); + +/** + * Sets the point to a new x and y position. + * If y is omitted, both x and y will be set to x. + * + * @param [x=0] {number} position of the point on the x axis + * @param [y=0] {number} position of the point on the y axis + */ +ObservablePoint.prototype.set = function (x, y) +{ + var _x = x || 0; + var _y = y || ( (y !== 0) ? _x : 0 ); + if (this._x !== _x || this._y !== _y) + { + this._x = _x; + this._y = _y; + this.cb.call(this.scope); + } +}; + +/** + * Copies the data from another point + * + * @param point {PIXI.Point|{PIXI.ObservablePoint} point to copy from + */ +ObservablePoint.prototype.copy = function (point) +{ + if (this._x !== point.x || this._y !== point.y) + { + this._x = point.x; + this._y = point.y; + this.cb.call(this.scope); + } +}; diff --git a/src/core/math/index.js b/src/core/math/index.js index a43f6e7..8f199d0 100644 --- a/src/core/math/index.js +++ b/src/core/math/index.js @@ -9,13 +9,14 @@ // to avoid circular dependencies and cut down on // internal module requires. - Point: require('./Point'), - Matrix: require('./Matrix'), - GroupD8: require('./GroupD8'), + Point: require('./Point'), + ObservablePoint: require('./ObservablePoint'), + Matrix: require('./Matrix'), + GroupD8: require('./GroupD8'), - Circle: require('./shapes/Circle'), - Ellipse: require('./shapes/Ellipse'), - Polygon: require('./shapes/Polygon'), - Rectangle: require('./shapes/Rectangle'), - RoundedRectangle: require('./shapes/RoundedRectangle') + Circle: require('./shapes/Circle'), + Ellipse: require('./shapes/Ellipse'), + Polygon: require('./shapes/Polygon'), + Rectangle: require('./shapes/Rectangle'), + RoundedRectangle: require('./shapes/RoundedRectangle') }; diff --git a/src/core/sprites/Sprite.js b/src/core/sprites/Sprite.js index b4350f7..6a60a81 100644 --- a/src/core/sprites/Sprite.js +++ b/src/core/sprites/Sprite.js @@ -31,7 +31,7 @@ * * @member {PIXI.Point} */ - this.anchor = new math.Point(); + this.anchor = new math.ObservablePoint(this.onAnchorUpdate, this); /** * The texture that the sprite is using @@ -91,8 +91,9 @@ // call texture setter this.texture = texture || Texture.EMPTY; - this.textureDirty = true; this.vertexData = new Float32Array(16); + this._transformID = -1; + this._textureID = -1; } // constructor @@ -160,7 +161,7 @@ this._texture = value; this.cachedTint = 0xFFFFFF; - this.textureDirty = true; + this._textureID = -1; if (value) { @@ -185,7 +186,7 @@ */ Sprite.prototype._onTextureUpdate = function () { - this.textureDirty = true; + this._textureID = -1; // so if _width is 0 then width was not set.. if (this._width) @@ -199,11 +200,26 @@ } }; +Sprite.prototype.onAnchorUpdate = function() +{ + this._transformID = -1; +}; + /** * calculates worldTransform * vertices, store it in vertexData */ Sprite.prototype.calculateVertices = function () { + if(this._transformID === this.transform._worldID && this._textureID === this._texture._updateID) + { + return; + } + + this._transformID = this.transform._worldID; + this._textureID = this._texture._updateID; + + // set the vertex data + var texture = this._texture, wt = this.transform.worldTransform, a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty, @@ -307,12 +323,7 @@ */ Sprite.prototype._renderWebGL = function (renderer) { - if(this.transform.updated || this.textureDirty) - { - this.textureDirty = false; - // set the vertex data - this.calculateVertices(); - } + this.calculateVertices(); renderer.setObjectRenderer(renderer.plugins.sprite); renderer.plugins.sprite.render(this); @@ -340,14 +351,11 @@ //TODO lookinto caching.. if(!this._currentBounds) { - // if(this.vertexDirty) - { - this.vertexDirty = false; + // set the vertex data + this.calculateVertices(); - // set the vertex data - this.calculateBoundsVertices(); - - } + // set the vertex data + this.calculateBoundsVertices(); var minX, maxX, minY, maxY, w0, w1, h0, h1, diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index e26e780..74c2699 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -132,6 +132,9 @@ * @memberof PIXI.Texture# * @protected */ + + + this._updateID = 0; } Texture.prototype = Object.create(EventEmitter.prototype); @@ -238,6 +241,8 @@ */ Texture.prototype.onBaseTextureLoaded = function (baseTexture) { + this._updateID++; + // TODO this code looks confusing.. boo to abusing getters and setterss! if (this.noFrame) { @@ -250,6 +255,7 @@ this.baseTexture.on('update', this.onBaseTextureUpdated, this); this.emit('update', this); + }; /** @@ -259,6 +265,8 @@ */ Texture.prototype.onBaseTextureUpdated = function (baseTexture) { + this._updateID++; + this._frame.width = baseTexture.width; this._frame.height = baseTexture.height; @@ -327,6 +335,8 @@ } this._uvs.set(this._frame, this.baseTexture, this.rotate); + + this._updateID++; }; /** diff --git a/src/extras/BitmapText.js b/src/extras/BitmapText.js index 6f1cdb9..dbe1c65 100644 --- a/src/extras/BitmapText.js +++ b/src/extras/BitmapText.js @@ -1,5 +1,5 @@ var core = require('../core'), - ObservablePoint = require('../core/display/ObservablePoint'); + ObservablePoint = require('../core/math/ObservablePoint'); /** * A BitmapText object will create a line or multiple lines of text using bitmap font. To diff --git a/src/core/const.js b/src/core/const.js index 57d08b9..3f9d5de 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -309,6 +309,12 @@ HIGH: 'highp' }, + TRANSFORM_MODE:{ + STATIC:0, + DYNAMIC:1, + DEFAULT:0 + }, + // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 SPRITE_BATCH_SIZE: 4096, //nice balance between mobile and desktop machines diff --git a/src/core/display/Container.js b/src/core/display/Container.js index 26d9e84..90575c7 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -131,6 +131,9 @@ child.parent = this; + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this.children.push(child); // TODO - lets either do all callbacks or all events.. not both! @@ -366,7 +369,7 @@ return; } - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); //TODO: check render flags, how to process stuff here this.worldAlpha = this.alpha * this.parent.worldAlpha; @@ -468,6 +471,7 @@ var matrixCache = this.transform.worldTransform; this.transform.worldTransform = math.Matrix.IDENTITY; + this.transform._worldID++; for (var i = 0, j = this.children.length; i < j; ++i) { @@ -475,6 +479,7 @@ } this.transform.worldTransform = matrixCache; + this.transform._worldID++; this._currentBounds = null; diff --git a/src/core/display/DisplayObject.js b/src/core/display/DisplayObject.js index 256489f..54a4017 100644 --- a/src/core/display/DisplayObject.js +++ b/src/core/display/DisplayObject.js @@ -1,5 +1,7 @@ var math = require('../math'), EventEmitter = require('eventemitter3'), + CONST = require('../const'), + TransformStatic = require('./TransformStatic'), Transform = require('./Transform'), _tempDisplayObjectParent = new DisplayObject(); @@ -17,12 +19,14 @@ { EventEmitter.call(this); + var TransformClass = CONST.TRANSFORM_MODE.DEFAULT === CONST.TRANSFORM_MODE.STATIC ? TransformStatic : Transform; + //TODO: need to create Transform from factory /** * World transform and local transform of this object. * This will be reworked in v4.1, please do not use it yet unless you know what are you doing! */ - this.transform = new Transform(); + this.transform = new TransformClass(); /** * The opacity of the object. @@ -322,7 +326,7 @@ */ DisplayObject.prototype.updateTransform = function () { - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); // multiply the alphas.. this.worldAlpha = this.alpha * this.parent.worldAlpha; }; diff --git a/src/core/display/ObservablePoint.js b/src/core/display/ObservablePoint.js deleted file mode 100644 index 836fcdd..0000000 --- a/src/core/display/ObservablePoint.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * The Point object represents a location in a two-dimensional coordinate system, where x represents - * the horizontal axis and y represents the vertical axis. - * An observable point is a point that triggers a callback when the point's position is changed. - * - * @class - * @memberof PIXI - * @param cb {Function} callback when changed - * @param scope {Object} owner of callback - * @param [x=0] {number} position of the point on the x axis - * @param [y=0] {number} position of the point on the y axis - */ -function ObservablePoint(cb, scope, x, y) -{ - this._x = x || 0; - this._y = y || 0; - - this.cb = cb; - this.scope = scope; -} - -ObservablePoint.prototype.constructor = ObservablePoint; -module.exports = ObservablePoint; - - - -Object.defineProperties(ObservablePoint.prototype, { - /** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @member {number} - * @memberof PIXI.ObservablePoint# - */ - x: { - get: function () - { - return this._x; - }, - set: function (value) - { - if (this._x !== value) { - this._x = value; - this.cb.call(this.scope); - } - } - }, - /** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @member {number} - * @memberof PIXI.ObservablePoint# - */ - y: { - get: function () - { - return this._y; - }, - set: function (value) - { - if (this._y !== value) { - this._y = value; - this.cb.call(this.scope); - } - } - } -}); - -/** - * Sets the point to a new x and y position. - * If y is omitted, both x and y will be set to x. - * - * @param [x=0] {number} position of the point on the x axis - * @param [y=0] {number} position of the point on the y axis - */ -ObservablePoint.prototype.set = function (x, y) -{ - var _x = x || 0; - var _y = y || ( (y !== 0) ? _x : 0 ); - if (this._x !== _x || this._y !== _y) - { - this._x = _x; - this._y = _y; - this.cb.call(this.scope); - } -}; - -/** - * Copies the data from another point - * - * @param point {PIXI.Point|{PIXI.ObservablePoint} point to copy from - */ -ObservablePoint.prototype.copy = function (point) -{ - if (this._x !== point.x || this._y !== point.y) - { - this._x = point.x; - this._y = point.y; - this.cb.call(this.scope); - } -}; diff --git a/src/core/display/Transform.js b/src/core/display/Transform.js index 2d1e90f..ee8bafb 100644 --- a/src/core/display/Transform.js +++ b/src/core/display/Transform.js @@ -1,5 +1,4 @@ -var math = require('../math'), - ObservablePoint = require('./ObservablePoint'); +var math = require('../math'); /** @@ -35,7 +34,7 @@ this.scale = new math.Point(1,1); - this.skew = new ObservablePoint(this.updateSkew, this, 0,0); + this.skew = new math.ObservablePoint(this.updateSkew, this, 0,0); /** * The pivot point of the displayObject that it rotates around @@ -60,6 +59,8 @@ this._dirty = false; this.updated = true; + + this._worldID = 0; } Transform.prototype.constructor = Transform; @@ -105,15 +106,10 @@ wt.d = lt.c * pt.b + lt.d * pt.d; wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; -}; -Transform.prototype.updateChildTransform = function (childTransform) -{ - childTransform.updateTransform(this); - return childTransform; + this._worldID ++; }; - /** * Decomposes a matrix and sets the transforms properties based on it. * @param {Matrix} diff --git a/src/core/display/TransformStatic.js b/src/core/display/TransformStatic.js index fcab61b..510b716 100644 --- a/src/core/display/TransformStatic.js +++ b/src/core/display/TransformStatic.js @@ -1,5 +1,4 @@ var math = require('../math'); -var ObservablePoint = require('./ObservablePoint'); /** * Transform that takes care about its versions @@ -24,40 +23,62 @@ * * @member {PIXI.ObservablePoint} */ - this.position = new ObservablePoint(this,0.0); + this.position = new math.ObservablePoint(this.onChange, this,0.0); /** * The scale factor of the object. * * @member {PIXI.ObservablePoint} */ - this.scale = new ObservablePoint(this,1,1); + this.scale = new math.ObservablePoint(this.onChange, this,1,1); /** * The pivot point of the displayObject that it rotates around * * @member {PIXI.ObservablePoint} */ - this.pivot = new ObservablePoint(this,0.0); + this.pivot = new math.ObservablePoint(this.onChange, this,0, 0); /** * The skew amount, on the x and y axis. * * @member {PIXI.ObservablePoint} */ - this.skew = new ObservablePoint(this,0.0); + this.skew = new math.ObservablePoint(this.updateSkew, this,0, 0); this._rotation = 0; + this._sr = Math.sin(0); this._cr = Math.cos(0); + this._cy = Math.cos(0);//skewY); + this._sy = Math.sin(0);//skewY); + this._nsx = Math.sin(0);//skewX); + this._cx = Math.cos(0);//skewX); - this._dirtyLocal = 0; - this._versionLocal = 0; - this._versionGlobal = 0; + + this._localID = 0; + this._currentLocalID = 0; + this._parentID = 0; + this._worldID = 0; } TransformStatic.prototype.constructor = TransformStatic; +TransformStatic.prototype.onChange = function () +{ + this._localID ++; +}; + +TransformStatic.prototype.updateSkew = function () +{ + this._cy = Math.cos(this.skew.y); + this._sy = Math.sin(this.skew.y); + this._nsx = Math.sin(this.skew.x); + this._cx = Math.cos(this.skew.x); + + this._localID ++; +}; + /** * Updates the values of the object and applies the parent's transform. * @param parentTransform {PIXI.Transform} The transform of the parent of this object @@ -69,35 +90,57 @@ var wt = this.worldTransform; var lt = this.localTransform; - if(this._dirtyLocal !== this._versionLocal) + if(this._localID !== this._currentLocalID) { // get the matrix values of the displayobject based on its transform properties.. - lt.a = this._cr * this.scale._x; - lt.b = this._sr * this.scale._x; - lt.c = -this._sr * this.scale._y; - lt.d = this._cr * this.scale._y; + var a,b,c,d; + + a = this._cr * this.scale.x; + b = this._sr * this.scale.x; + c = -this._sr * this.scale.y; + d = this._cr * this.scale.y; + + lt.a = this._cy * a + this._sy * c; + lt.b = this._cy * b + this._sy * d; + lt.c = this._nsx * a + this._cx * c; + lt.d = this._nsx * b + this._cx * d; + lt.tx = this.position._x - (this.pivot._x * lt.a + this.pivot._y * lt.c); lt.ty = this.position._y - (this.pivot._x * lt.b + this.pivot._y * lt.d); - this._dirtyLocal = this._versionLocal; + this._currentLocalID = this._localID; + + // force an update.. + this._parentID = -1; } - // concat the parent matrix with the objects transform. - wt.a = lt.a * pt.a + lt.b * pt.c; - wt.b = lt.a * pt.b + lt.b * pt.d; - wt.c = lt.c * pt.a + lt.d * pt.c; - wt.d = lt.c * pt.b + lt.d * pt.d; - wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; - wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; - this._versionGlobal++; - this.updated = true; + if(this._parentID !== parentTransform._worldID) + { + // concat the parent matrix with the objects transform. + wt.a = lt.a * pt.a + lt.b * pt.c; + wt.b = lt.a * pt.b + lt.b * pt.d; + wt.c = lt.c * pt.a + lt.d * pt.c; + wt.d = lt.c * pt.b + lt.d * pt.d; + wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; + wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; + + this._parentID = parentTransform._worldID; + + // update the id of the transform.. + this._worldID ++; + } }; -TransformStatic.prototype.updateChildTransform = function (childTransform) +/** + * Decomposes a matrix and sets the transforms properties based on it. + * @param {Matrix} + */ +TransformStatic.prototype.setFromMatrix = function (matrix) { - childTransform.updateTransform(this); - return childTransform; + matrix.decompose(this); }; + + Object.defineProperties(TransformStatic.prototype, { /** * The rotation of the object in radians. @@ -112,6 +155,7 @@ this._rotation = value; this._sr = Math.sin(value); this._cr = Math.cos(value); + this._localID ++; } } }); diff --git a/src/core/math/ObservablePoint.js b/src/core/math/ObservablePoint.js new file mode 100644 index 0000000..836fcdd --- /dev/null +++ b/src/core/math/ObservablePoint.js @@ -0,0 +1,100 @@ +/** + * The Point object represents a location in a two-dimensional coordinate system, where x represents + * the horizontal axis and y represents the vertical axis. + * An observable point is a point that triggers a callback when the point's position is changed. + * + * @class + * @memberof PIXI + * @param cb {Function} callback when changed + * @param scope {Object} owner of callback + * @param [x=0] {number} position of the point on the x axis + * @param [y=0] {number} position of the point on the y axis + */ +function ObservablePoint(cb, scope, x, y) +{ + this._x = x || 0; + this._y = y || 0; + + this.cb = cb; + this.scope = scope; +} + +ObservablePoint.prototype.constructor = ObservablePoint; +module.exports = ObservablePoint; + + + +Object.defineProperties(ObservablePoint.prototype, { + /** + * The position of the displayObject on the x axis relative to the local coordinates of the parent. + * + * @member {number} + * @memberof PIXI.ObservablePoint# + */ + x: { + get: function () + { + return this._x; + }, + set: function (value) + { + if (this._x !== value) { + this._x = value; + this.cb.call(this.scope); + } + } + }, + /** + * The position of the displayObject on the x axis relative to the local coordinates of the parent. + * + * @member {number} + * @memberof PIXI.ObservablePoint# + */ + y: { + get: function () + { + return this._y; + }, + set: function (value) + { + if (this._y !== value) { + this._y = value; + this.cb.call(this.scope); + } + } + } +}); + +/** + * Sets the point to a new x and y position. + * If y is omitted, both x and y will be set to x. + * + * @param [x=0] {number} position of the point on the x axis + * @param [y=0] {number} position of the point on the y axis + */ +ObservablePoint.prototype.set = function (x, y) +{ + var _x = x || 0; + var _y = y || ( (y !== 0) ? _x : 0 ); + if (this._x !== _x || this._y !== _y) + { + this._x = _x; + this._y = _y; + this.cb.call(this.scope); + } +}; + +/** + * Copies the data from another point + * + * @param point {PIXI.Point|{PIXI.ObservablePoint} point to copy from + */ +ObservablePoint.prototype.copy = function (point) +{ + if (this._x !== point.x || this._y !== point.y) + { + this._x = point.x; + this._y = point.y; + this.cb.call(this.scope); + } +}; diff --git a/src/core/math/index.js b/src/core/math/index.js index a43f6e7..8f199d0 100644 --- a/src/core/math/index.js +++ b/src/core/math/index.js @@ -9,13 +9,14 @@ // to avoid circular dependencies and cut down on // internal module requires. - Point: require('./Point'), - Matrix: require('./Matrix'), - GroupD8: require('./GroupD8'), + Point: require('./Point'), + ObservablePoint: require('./ObservablePoint'), + Matrix: require('./Matrix'), + GroupD8: require('./GroupD8'), - Circle: require('./shapes/Circle'), - Ellipse: require('./shapes/Ellipse'), - Polygon: require('./shapes/Polygon'), - Rectangle: require('./shapes/Rectangle'), - RoundedRectangle: require('./shapes/RoundedRectangle') + Circle: require('./shapes/Circle'), + Ellipse: require('./shapes/Ellipse'), + Polygon: require('./shapes/Polygon'), + Rectangle: require('./shapes/Rectangle'), + RoundedRectangle: require('./shapes/RoundedRectangle') }; diff --git a/src/core/sprites/Sprite.js b/src/core/sprites/Sprite.js index b4350f7..6a60a81 100644 --- a/src/core/sprites/Sprite.js +++ b/src/core/sprites/Sprite.js @@ -31,7 +31,7 @@ * * @member {PIXI.Point} */ - this.anchor = new math.Point(); + this.anchor = new math.ObservablePoint(this.onAnchorUpdate, this); /** * The texture that the sprite is using @@ -91,8 +91,9 @@ // call texture setter this.texture = texture || Texture.EMPTY; - this.textureDirty = true; this.vertexData = new Float32Array(16); + this._transformID = -1; + this._textureID = -1; } // constructor @@ -160,7 +161,7 @@ this._texture = value; this.cachedTint = 0xFFFFFF; - this.textureDirty = true; + this._textureID = -1; if (value) { @@ -185,7 +186,7 @@ */ Sprite.prototype._onTextureUpdate = function () { - this.textureDirty = true; + this._textureID = -1; // so if _width is 0 then width was not set.. if (this._width) @@ -199,11 +200,26 @@ } }; +Sprite.prototype.onAnchorUpdate = function() +{ + this._transformID = -1; +}; + /** * calculates worldTransform * vertices, store it in vertexData */ Sprite.prototype.calculateVertices = function () { + if(this._transformID === this.transform._worldID && this._textureID === this._texture._updateID) + { + return; + } + + this._transformID = this.transform._worldID; + this._textureID = this._texture._updateID; + + // set the vertex data + var texture = this._texture, wt = this.transform.worldTransform, a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty, @@ -307,12 +323,7 @@ */ Sprite.prototype._renderWebGL = function (renderer) { - if(this.transform.updated || this.textureDirty) - { - this.textureDirty = false; - // set the vertex data - this.calculateVertices(); - } + this.calculateVertices(); renderer.setObjectRenderer(renderer.plugins.sprite); renderer.plugins.sprite.render(this); @@ -340,14 +351,11 @@ //TODO lookinto caching.. if(!this._currentBounds) { - // if(this.vertexDirty) - { - this.vertexDirty = false; + // set the vertex data + this.calculateVertices(); - // set the vertex data - this.calculateBoundsVertices(); - - } + // set the vertex data + this.calculateBoundsVertices(); var minX, maxX, minY, maxY, w0, w1, h0, h1, diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index e26e780..74c2699 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -132,6 +132,9 @@ * @memberof PIXI.Texture# * @protected */ + + + this._updateID = 0; } Texture.prototype = Object.create(EventEmitter.prototype); @@ -238,6 +241,8 @@ */ Texture.prototype.onBaseTextureLoaded = function (baseTexture) { + this._updateID++; + // TODO this code looks confusing.. boo to abusing getters and setterss! if (this.noFrame) { @@ -250,6 +255,7 @@ this.baseTexture.on('update', this.onBaseTextureUpdated, this); this.emit('update', this); + }; /** @@ -259,6 +265,8 @@ */ Texture.prototype.onBaseTextureUpdated = function (baseTexture) { + this._updateID++; + this._frame.width = baseTexture.width; this._frame.height = baseTexture.height; @@ -327,6 +335,8 @@ } this._uvs.set(this._frame, this.baseTexture, this.rotate); + + this._updateID++; }; /** diff --git a/src/extras/BitmapText.js b/src/extras/BitmapText.js index 6f1cdb9..dbe1c65 100644 --- a/src/extras/BitmapText.js +++ b/src/extras/BitmapText.js @@ -1,5 +1,5 @@ var core = require('../core'), - ObservablePoint = require('../core/display/ObservablePoint'); + ObservablePoint = require('../core/math/ObservablePoint'); /** * A BitmapText object will create a line or multiple lines of text using bitmap font. To diff --git a/src/extras/cacheAsBitmap.js b/src/extras/cacheAsBitmap.js index 43c73f5..8c5225c 100644 --- a/src/extras/cacheAsBitmap.js +++ b/src/extras/cacheAsBitmap.js @@ -87,7 +87,7 @@ this._initCachedDisplayObject( renderer ); - this._cachedSprite.transform.updated = true; + this._cachedSprite._transformID = -1; this._cachedSprite.worldAlpha = this.worldAlpha; this._cachedSprite._renderWebGL(renderer); diff --git a/src/core/const.js b/src/core/const.js index 57d08b9..3f9d5de 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -309,6 +309,12 @@ HIGH: 'highp' }, + TRANSFORM_MODE:{ + STATIC:0, + DYNAMIC:1, + DEFAULT:0 + }, + // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 SPRITE_BATCH_SIZE: 4096, //nice balance between mobile and desktop machines diff --git a/src/core/display/Container.js b/src/core/display/Container.js index 26d9e84..90575c7 100644 --- a/src/core/display/Container.js +++ b/src/core/display/Container.js @@ -131,6 +131,9 @@ child.parent = this; + // ensure a transform will be recalculated.. + this.transform._parentID = -1; + this.children.push(child); // TODO - lets either do all callbacks or all events.. not both! @@ -366,7 +369,7 @@ return; } - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); //TODO: check render flags, how to process stuff here this.worldAlpha = this.alpha * this.parent.worldAlpha; @@ -468,6 +471,7 @@ var matrixCache = this.transform.worldTransform; this.transform.worldTransform = math.Matrix.IDENTITY; + this.transform._worldID++; for (var i = 0, j = this.children.length; i < j; ++i) { @@ -475,6 +479,7 @@ } this.transform.worldTransform = matrixCache; + this.transform._worldID++; this._currentBounds = null; diff --git a/src/core/display/DisplayObject.js b/src/core/display/DisplayObject.js index 256489f..54a4017 100644 --- a/src/core/display/DisplayObject.js +++ b/src/core/display/DisplayObject.js @@ -1,5 +1,7 @@ var math = require('../math'), EventEmitter = require('eventemitter3'), + CONST = require('../const'), + TransformStatic = require('./TransformStatic'), Transform = require('./Transform'), _tempDisplayObjectParent = new DisplayObject(); @@ -17,12 +19,14 @@ { EventEmitter.call(this); + var TransformClass = CONST.TRANSFORM_MODE.DEFAULT === CONST.TRANSFORM_MODE.STATIC ? TransformStatic : Transform; + //TODO: need to create Transform from factory /** * World transform and local transform of this object. * This will be reworked in v4.1, please do not use it yet unless you know what are you doing! */ - this.transform = new Transform(); + this.transform = new TransformClass(); /** * The opacity of the object. @@ -322,7 +326,7 @@ */ DisplayObject.prototype.updateTransform = function () { - this.transform = this.parent.transform.updateChildTransform(this.transform); + this.transform.updateTransform(this.parent.transform); // multiply the alphas.. this.worldAlpha = this.alpha * this.parent.worldAlpha; }; diff --git a/src/core/display/ObservablePoint.js b/src/core/display/ObservablePoint.js deleted file mode 100644 index 836fcdd..0000000 --- a/src/core/display/ObservablePoint.js +++ /dev/null @@ -1,100 +0,0 @@ -/** - * The Point object represents a location in a two-dimensional coordinate system, where x represents - * the horizontal axis and y represents the vertical axis. - * An observable point is a point that triggers a callback when the point's position is changed. - * - * @class - * @memberof PIXI - * @param cb {Function} callback when changed - * @param scope {Object} owner of callback - * @param [x=0] {number} position of the point on the x axis - * @param [y=0] {number} position of the point on the y axis - */ -function ObservablePoint(cb, scope, x, y) -{ - this._x = x || 0; - this._y = y || 0; - - this.cb = cb; - this.scope = scope; -} - -ObservablePoint.prototype.constructor = ObservablePoint; -module.exports = ObservablePoint; - - - -Object.defineProperties(ObservablePoint.prototype, { - /** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @member {number} - * @memberof PIXI.ObservablePoint# - */ - x: { - get: function () - { - return this._x; - }, - set: function (value) - { - if (this._x !== value) { - this._x = value; - this.cb.call(this.scope); - } - } - }, - /** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @member {number} - * @memberof PIXI.ObservablePoint# - */ - y: { - get: function () - { - return this._y; - }, - set: function (value) - { - if (this._y !== value) { - this._y = value; - this.cb.call(this.scope); - } - } - } -}); - -/** - * Sets the point to a new x and y position. - * If y is omitted, both x and y will be set to x. - * - * @param [x=0] {number} position of the point on the x axis - * @param [y=0] {number} position of the point on the y axis - */ -ObservablePoint.prototype.set = function (x, y) -{ - var _x = x || 0; - var _y = y || ( (y !== 0) ? _x : 0 ); - if (this._x !== _x || this._y !== _y) - { - this._x = _x; - this._y = _y; - this.cb.call(this.scope); - } -}; - -/** - * Copies the data from another point - * - * @param point {PIXI.Point|{PIXI.ObservablePoint} point to copy from - */ -ObservablePoint.prototype.copy = function (point) -{ - if (this._x !== point.x || this._y !== point.y) - { - this._x = point.x; - this._y = point.y; - this.cb.call(this.scope); - } -}; diff --git a/src/core/display/Transform.js b/src/core/display/Transform.js index 2d1e90f..ee8bafb 100644 --- a/src/core/display/Transform.js +++ b/src/core/display/Transform.js @@ -1,5 +1,4 @@ -var math = require('../math'), - ObservablePoint = require('./ObservablePoint'); +var math = require('../math'); /** @@ -35,7 +34,7 @@ this.scale = new math.Point(1,1); - this.skew = new ObservablePoint(this.updateSkew, this, 0,0); + this.skew = new math.ObservablePoint(this.updateSkew, this, 0,0); /** * The pivot point of the displayObject that it rotates around @@ -60,6 +59,8 @@ this._dirty = false; this.updated = true; + + this._worldID = 0; } Transform.prototype.constructor = Transform; @@ -105,15 +106,10 @@ wt.d = lt.c * pt.b + lt.d * pt.d; wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; -}; -Transform.prototype.updateChildTransform = function (childTransform) -{ - childTransform.updateTransform(this); - return childTransform; + this._worldID ++; }; - /** * Decomposes a matrix and sets the transforms properties based on it. * @param {Matrix} diff --git a/src/core/display/TransformStatic.js b/src/core/display/TransformStatic.js index fcab61b..510b716 100644 --- a/src/core/display/TransformStatic.js +++ b/src/core/display/TransformStatic.js @@ -1,5 +1,4 @@ var math = require('../math'); -var ObservablePoint = require('./ObservablePoint'); /** * Transform that takes care about its versions @@ -24,40 +23,62 @@ * * @member {PIXI.ObservablePoint} */ - this.position = new ObservablePoint(this,0.0); + this.position = new math.ObservablePoint(this.onChange, this,0.0); /** * The scale factor of the object. * * @member {PIXI.ObservablePoint} */ - this.scale = new ObservablePoint(this,1,1); + this.scale = new math.ObservablePoint(this.onChange, this,1,1); /** * The pivot point of the displayObject that it rotates around * * @member {PIXI.ObservablePoint} */ - this.pivot = new ObservablePoint(this,0.0); + this.pivot = new math.ObservablePoint(this.onChange, this,0, 0); /** * The skew amount, on the x and y axis. * * @member {PIXI.ObservablePoint} */ - this.skew = new ObservablePoint(this,0.0); + this.skew = new math.ObservablePoint(this.updateSkew, this,0, 0); this._rotation = 0; + this._sr = Math.sin(0); this._cr = Math.cos(0); + this._cy = Math.cos(0);//skewY); + this._sy = Math.sin(0);//skewY); + this._nsx = Math.sin(0);//skewX); + this._cx = Math.cos(0);//skewX); - this._dirtyLocal = 0; - this._versionLocal = 0; - this._versionGlobal = 0; + + this._localID = 0; + this._currentLocalID = 0; + this._parentID = 0; + this._worldID = 0; } TransformStatic.prototype.constructor = TransformStatic; +TransformStatic.prototype.onChange = function () +{ + this._localID ++; +}; + +TransformStatic.prototype.updateSkew = function () +{ + this._cy = Math.cos(this.skew.y); + this._sy = Math.sin(this.skew.y); + this._nsx = Math.sin(this.skew.x); + this._cx = Math.cos(this.skew.x); + + this._localID ++; +}; + /** * Updates the values of the object and applies the parent's transform. * @param parentTransform {PIXI.Transform} The transform of the parent of this object @@ -69,35 +90,57 @@ var wt = this.worldTransform; var lt = this.localTransform; - if(this._dirtyLocal !== this._versionLocal) + if(this._localID !== this._currentLocalID) { // get the matrix values of the displayobject based on its transform properties.. - lt.a = this._cr * this.scale._x; - lt.b = this._sr * this.scale._x; - lt.c = -this._sr * this.scale._y; - lt.d = this._cr * this.scale._y; + var a,b,c,d; + + a = this._cr * this.scale.x; + b = this._sr * this.scale.x; + c = -this._sr * this.scale.y; + d = this._cr * this.scale.y; + + lt.a = this._cy * a + this._sy * c; + lt.b = this._cy * b + this._sy * d; + lt.c = this._nsx * a + this._cx * c; + lt.d = this._nsx * b + this._cx * d; + lt.tx = this.position._x - (this.pivot._x * lt.a + this.pivot._y * lt.c); lt.ty = this.position._y - (this.pivot._x * lt.b + this.pivot._y * lt.d); - this._dirtyLocal = this._versionLocal; + this._currentLocalID = this._localID; + + // force an update.. + this._parentID = -1; } - // concat the parent matrix with the objects transform. - wt.a = lt.a * pt.a + lt.b * pt.c; - wt.b = lt.a * pt.b + lt.b * pt.d; - wt.c = lt.c * pt.a + lt.d * pt.c; - wt.d = lt.c * pt.b + lt.d * pt.d; - wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; - wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; - this._versionGlobal++; - this.updated = true; + if(this._parentID !== parentTransform._worldID) + { + // concat the parent matrix with the objects transform. + wt.a = lt.a * pt.a + lt.b * pt.c; + wt.b = lt.a * pt.b + lt.b * pt.d; + wt.c = lt.c * pt.a + lt.d * pt.c; + wt.d = lt.c * pt.b + lt.d * pt.d; + wt.tx = lt.tx * pt.a + lt.ty * pt.c + pt.tx; + wt.ty = lt.tx * pt.b + lt.ty * pt.d + pt.ty; + + this._parentID = parentTransform._worldID; + + // update the id of the transform.. + this._worldID ++; + } }; -TransformStatic.prototype.updateChildTransform = function (childTransform) +/** + * Decomposes a matrix and sets the transforms properties based on it. + * @param {Matrix} + */ +TransformStatic.prototype.setFromMatrix = function (matrix) { - childTransform.updateTransform(this); - return childTransform; + matrix.decompose(this); }; + + Object.defineProperties(TransformStatic.prototype, { /** * The rotation of the object in radians. @@ -112,6 +155,7 @@ this._rotation = value; this._sr = Math.sin(value); this._cr = Math.cos(value); + this._localID ++; } } }); diff --git a/src/core/math/ObservablePoint.js b/src/core/math/ObservablePoint.js new file mode 100644 index 0000000..836fcdd --- /dev/null +++ b/src/core/math/ObservablePoint.js @@ -0,0 +1,100 @@ +/** + * The Point object represents a location in a two-dimensional coordinate system, where x represents + * the horizontal axis and y represents the vertical axis. + * An observable point is a point that triggers a callback when the point's position is changed. + * + * @class + * @memberof PIXI + * @param cb {Function} callback when changed + * @param scope {Object} owner of callback + * @param [x=0] {number} position of the point on the x axis + * @param [y=0] {number} position of the point on the y axis + */ +function ObservablePoint(cb, scope, x, y) +{ + this._x = x || 0; + this._y = y || 0; + + this.cb = cb; + this.scope = scope; +} + +ObservablePoint.prototype.constructor = ObservablePoint; +module.exports = ObservablePoint; + + + +Object.defineProperties(ObservablePoint.prototype, { + /** + * The position of the displayObject on the x axis relative to the local coordinates of the parent. + * + * @member {number} + * @memberof PIXI.ObservablePoint# + */ + x: { + get: function () + { + return this._x; + }, + set: function (value) + { + if (this._x !== value) { + this._x = value; + this.cb.call(this.scope); + } + } + }, + /** + * The position of the displayObject on the x axis relative to the local coordinates of the parent. + * + * @member {number} + * @memberof PIXI.ObservablePoint# + */ + y: { + get: function () + { + return this._y; + }, + set: function (value) + { + if (this._y !== value) { + this._y = value; + this.cb.call(this.scope); + } + } + } +}); + +/** + * Sets the point to a new x and y position. + * If y is omitted, both x and y will be set to x. + * + * @param [x=0] {number} position of the point on the x axis + * @param [y=0] {number} position of the point on the y axis + */ +ObservablePoint.prototype.set = function (x, y) +{ + var _x = x || 0; + var _y = y || ( (y !== 0) ? _x : 0 ); + if (this._x !== _x || this._y !== _y) + { + this._x = _x; + this._y = _y; + this.cb.call(this.scope); + } +}; + +/** + * Copies the data from another point + * + * @param point {PIXI.Point|{PIXI.ObservablePoint} point to copy from + */ +ObservablePoint.prototype.copy = function (point) +{ + if (this._x !== point.x || this._y !== point.y) + { + this._x = point.x; + this._y = point.y; + this.cb.call(this.scope); + } +}; diff --git a/src/core/math/index.js b/src/core/math/index.js index a43f6e7..8f199d0 100644 --- a/src/core/math/index.js +++ b/src/core/math/index.js @@ -9,13 +9,14 @@ // to avoid circular dependencies and cut down on // internal module requires. - Point: require('./Point'), - Matrix: require('./Matrix'), - GroupD8: require('./GroupD8'), + Point: require('./Point'), + ObservablePoint: require('./ObservablePoint'), + Matrix: require('./Matrix'), + GroupD8: require('./GroupD8'), - Circle: require('./shapes/Circle'), - Ellipse: require('./shapes/Ellipse'), - Polygon: require('./shapes/Polygon'), - Rectangle: require('./shapes/Rectangle'), - RoundedRectangle: require('./shapes/RoundedRectangle') + Circle: require('./shapes/Circle'), + Ellipse: require('./shapes/Ellipse'), + Polygon: require('./shapes/Polygon'), + Rectangle: require('./shapes/Rectangle'), + RoundedRectangle: require('./shapes/RoundedRectangle') }; diff --git a/src/core/sprites/Sprite.js b/src/core/sprites/Sprite.js index b4350f7..6a60a81 100644 --- a/src/core/sprites/Sprite.js +++ b/src/core/sprites/Sprite.js @@ -31,7 +31,7 @@ * * @member {PIXI.Point} */ - this.anchor = new math.Point(); + this.anchor = new math.ObservablePoint(this.onAnchorUpdate, this); /** * The texture that the sprite is using @@ -91,8 +91,9 @@ // call texture setter this.texture = texture || Texture.EMPTY; - this.textureDirty = true; this.vertexData = new Float32Array(16); + this._transformID = -1; + this._textureID = -1; } // constructor @@ -160,7 +161,7 @@ this._texture = value; this.cachedTint = 0xFFFFFF; - this.textureDirty = true; + this._textureID = -1; if (value) { @@ -185,7 +186,7 @@ */ Sprite.prototype._onTextureUpdate = function () { - this.textureDirty = true; + this._textureID = -1; // so if _width is 0 then width was not set.. if (this._width) @@ -199,11 +200,26 @@ } }; +Sprite.prototype.onAnchorUpdate = function() +{ + this._transformID = -1; +}; + /** * calculates worldTransform * vertices, store it in vertexData */ Sprite.prototype.calculateVertices = function () { + if(this._transformID === this.transform._worldID && this._textureID === this._texture._updateID) + { + return; + } + + this._transformID = this.transform._worldID; + this._textureID = this._texture._updateID; + + // set the vertex data + var texture = this._texture, wt = this.transform.worldTransform, a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty, @@ -307,12 +323,7 @@ */ Sprite.prototype._renderWebGL = function (renderer) { - if(this.transform.updated || this.textureDirty) - { - this.textureDirty = false; - // set the vertex data - this.calculateVertices(); - } + this.calculateVertices(); renderer.setObjectRenderer(renderer.plugins.sprite); renderer.plugins.sprite.render(this); @@ -340,14 +351,11 @@ //TODO lookinto caching.. if(!this._currentBounds) { - // if(this.vertexDirty) - { - this.vertexDirty = false; + // set the vertex data + this.calculateVertices(); - // set the vertex data - this.calculateBoundsVertices(); - - } + // set the vertex data + this.calculateBoundsVertices(); var minX, maxX, minY, maxY, w0, w1, h0, h1, diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index e26e780..74c2699 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -132,6 +132,9 @@ * @memberof PIXI.Texture# * @protected */ + + + this._updateID = 0; } Texture.prototype = Object.create(EventEmitter.prototype); @@ -238,6 +241,8 @@ */ Texture.prototype.onBaseTextureLoaded = function (baseTexture) { + this._updateID++; + // TODO this code looks confusing.. boo to abusing getters and setterss! if (this.noFrame) { @@ -250,6 +255,7 @@ this.baseTexture.on('update', this.onBaseTextureUpdated, this); this.emit('update', this); + }; /** @@ -259,6 +265,8 @@ */ Texture.prototype.onBaseTextureUpdated = function (baseTexture) { + this._updateID++; + this._frame.width = baseTexture.width; this._frame.height = baseTexture.height; @@ -327,6 +335,8 @@ } this._uvs.set(this._frame, this.baseTexture, this.rotate); + + this._updateID++; }; /** diff --git a/src/extras/BitmapText.js b/src/extras/BitmapText.js index 6f1cdb9..dbe1c65 100644 --- a/src/extras/BitmapText.js +++ b/src/extras/BitmapText.js @@ -1,5 +1,5 @@ var core = require('../core'), - ObservablePoint = require('../core/display/ObservablePoint'); + ObservablePoint = require('../core/math/ObservablePoint'); /** * A BitmapText object will create a line or multiple lines of text using bitmap font. To diff --git a/src/extras/cacheAsBitmap.js b/src/extras/cacheAsBitmap.js index 43c73f5..8c5225c 100644 --- a/src/extras/cacheAsBitmap.js +++ b/src/extras/cacheAsBitmap.js @@ -87,7 +87,7 @@ this._initCachedDisplayObject( renderer ); - this._cachedSprite.transform.updated = true; + this._cachedSprite._transformID = -1; this._cachedSprite.worldAlpha = this.worldAlpha; this._cachedSprite._renderWebGL(renderer); diff --git a/src/mesh/Mesh.js b/src/mesh/Mesh.js index fd60ae2..0e95c05 100644 --- a/src/mesh/Mesh.js +++ b/src/mesh/Mesh.js @@ -412,7 +412,7 @@ */ Mesh.prototype._onTextureUpdate = function () { - this.updateFrame = true; + }; /**