diff --git a/CCBoot.js b/CCBoot.js
index a366001d74..22c50494b6 100644
--- a/CCBoot.js
+++ b/CCBoot.js
@@ -82,6 +82,8 @@ cc._canvas = null;
cc.container = null;
cc._gameDiv = null;
+window.ENABLE_IMAEG_POOL = true;
+
/**
* Iterate over an object or an array, executing a function for each matched element.
* @param {object|array} obj
@@ -583,6 +585,33 @@ cc.path = /** @lends cc.path# */{
* @see cc.loader
*/
+var imagePool = {
+ _pool: new Array(10),
+ _MAX: 10,
+ _smallImg: "data:image/gif;base64,R0lGODlhAQABAAAAACwAAAAAAQABAAA=",
+
+ count: 0,
+ get: function () {
+ if (this.count > 0) {
+ this.count--;
+ var result = this._pool[this.count];
+ this._pool[this.count] = null;
+ return result;
+ }
+ else {
+ return new Image();
+ }
+ },
+ put: function (img) {
+ var pool = this._pool;
+ if (img instanceof HTMLImageElement && this.count < this._MAX) {
+ img.src = this._smallImg;
+ pool[this.count] = img;
+ this.count++;
+ }
+ }
+};
+
/**
* Singleton instance of cc.Loader.
* @name cc.loader
@@ -768,29 +797,55 @@ cc.loader = (function () {
xhr.setRequestHeader("Accept-Charset", "utf-8");
xhr.onreadystatechange = function () {
if (xhr.readyState === 4)
- xhr.status === 200 ? cb(null, xhr.responseText) : cb({status:xhr.status, errorMessage:errInfo}, null);
+ (xhr.status === 200||xhr.status === 0) ? cb(null, xhr.responseText) : cb({status:xhr.status, errorMessage:errInfo}, null);
};
} else {
if (xhr.overrideMimeType) xhr.overrideMimeType("text\/plain; charset=utf-8");
- xhr.onload = function () {
+ var loadCallback = function () {
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
if (xhr._timeoutId >= 0) {
clearTimeout(xhr._timeoutId);
}
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
if (xhr.readyState === 4) {
- xhr.status === 200 ? cb(null, xhr.responseText) : cb({status:xhr.status, errorMessage:errInfo}, null);
+ (xhr.status === 200||xhr.status === 0) ? cb(null, xhr.responseText) : cb({status:xhr.status, errorMessage:errInfo}, null);
}
};
- xhr.onerror = function () {
+ var errorCallback = function () {
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
+ if (xhr._timeoutId >= 0) {
+ clearTimeout(xhr._timeoutId);
+ }
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
cb({status: xhr.status, errorMessage: errInfo}, null);
};
+ var timeoutCallback = function () {
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
+ if (xhr._timeoutId >= 0) {
+ clearTimeout(xhr._timeoutId);
+ }
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
+ cb({status: xhr.status, errorMessage: "Request timeout: " + errInfo}, null);
+ };
+ xhr.addEventListener('load', loadCallback);
+ xhr.addEventListener('error', errorCallback);
if (xhr.ontimeout === undefined) {
xhr._timeoutId = setTimeout(function () {
- xhr.ontimeout();
+ timeoutCallback();
}, xhr.timeout);
}
- xhr.ontimeout = function () {
- cb({status: xhr.status, errorMessage: "Request timeout: " + errInfo}, null);
- };
+ else {
+ xhr.addEventListener('timeout', timeoutCallback);
+ }
}
xhr.send(null);
} else {
@@ -807,29 +862,55 @@ cc.loader = (function () {
xhr.open("GET", url, true);
xhr.responseType = "arraybuffer";
- xhr.onload = function () {
+ var loadCallback = function () {
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
if (xhr._timeoutId >= 0) {
clearTimeout(xhr._timeoutId);
}
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
var arrayBuffer = xhr.response; // Note: not oReq.responseText
if (arrayBuffer) {
window.msg = arrayBuffer;
}
if (xhr.readyState === 4) {
- xhr.status === 200 ? cb(null, xhr.response) : cb({status:xhr.status, errorMessage:errInfo}, null);
+ (xhr.status === 200||xhr.status === 0) ? cb(null, xhr.response) : cb({status:xhr.status, errorMessage:errInfo}, null);
}
};
- xhr.onerror = function(){
+ var errorCallback = function(){
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
+ if (xhr._timeoutId >= 0) {
+ clearTimeout(xhr._timeoutId);
+ }
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
cb({status:xhr.status, errorMessage:errInfo}, null);
};
+ var timeoutCallback = function () {
+ xhr.removeEventListener('load', loadCallback);
+ xhr.removeEventListener('error', errorCallback);
+ if (xhr._timeoutId >= 0) {
+ clearTimeout(xhr._timeoutId);
+ }
+ else {
+ xhr.removeEventListener('timeout', timeoutCallback);
+ }
+ cb({status: xhr.status, errorMessage: "Request timeout: " + errInfo}, null);
+ };
+ xhr.addEventListener('load', loadCallback);
+ xhr.addEventListener('error', errorCallback);
if (xhr.ontimeout === undefined) {
xhr._timeoutId = setTimeout(function () {
- xhr.ontimeout();
+ timeoutCallback();
}, xhr.timeout);
}
- xhr.ontimeout = function () {
- cb({status: xhr.status, errorMessage: "Request timeout: " + errInfo}, null);
- };
+ else {
+ xhr.addEventListener('timeout', timeoutCallback);
+ }
xhr.send(null);
},
@@ -867,7 +948,7 @@ cc.loader = (function () {
* @param {function} callback
* @returns {Image}
*/
- loadImg: function (url, option, callback) {
+ loadImg: function (url, option, callback, img) {
var opt = {
isCrossOrigin: true
};
@@ -876,10 +957,10 @@ cc.loader = (function () {
else if (option !== undefined)
callback = option;
- var img = this.getRes(url);
- if (img) {
- callback && callback(null, img);
- return img;
+ var texture = this.getRes(url);
+ if (texture) {
+ callback && callback(null, texture);
+ return null;
}
var queue = _queue[url];
@@ -888,18 +969,16 @@ cc.loader = (function () {
return queue.img;
}
- img = new Image();
+ img = img || imagePool.get();
if (opt.isCrossOrigin && location.origin !== "file://")
img.crossOrigin = "Anonymous";
+ else
+ img.crossOrigin = null;
var loadCallback = function () {
this.removeEventListener('load', loadCallback, false);
this.removeEventListener('error', errorCallback, false);
- if (!_urlRegExp.test(url)) {
- cc.loader.cache[url] = img;
- }
-
var queue = _queue[url];
if (queue) {
var callbacks = queue.callbacks;
@@ -912,6 +991,10 @@ cc.loader = (function () {
queue.img = null;
delete _queue[url];
}
+
+ if (window.ENABLE_IMAEG_POOL && cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ imagePool.put(img);
+ }
};
var self = this;
@@ -919,10 +1002,10 @@ cc.loader = (function () {
this.removeEventListener('load', loadCallback, false);
this.removeEventListener('error', errorCallback, false);
- if (img.crossOrigin && img.crossOrigin.toLowerCase() === "anonymous") {
+ if (window.location.protocol !== 'https:' && img.crossOrigin && img.crossOrigin.toLowerCase() === "anonymous") {
opt.isCrossOrigin = false;
self.release(url);
- cc.loader.loadImg(url, opt, callback);
+ cc.loader.loadImg(url, opt, callback, img);
} else {
var queue = _queue[url];
if (queue) {
@@ -936,6 +1019,10 @@ cc.loader = (function () {
queue.img = null;
delete _queue[url];
}
+
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ imagePool.put(img);
+ }
}
};
@@ -977,7 +1064,7 @@ cc.loader = (function () {
loader = _register[type.toLowerCase()];
}
if (!loader) {
- cc.error("loader for [" + type + "] not exists!");
+ cc.error("loader for [" + type + "] doesn't exist!");
return cb();
}
var realUrl = url;
@@ -2669,7 +2756,7 @@ cc.game = /** @lends cc.game# */{
}
width = width || element.clientWidth;
height = height || element.clientHeight;
- this.canvas = cc._canvas = localCanvas = document.createElement("CANVAS");
+ this.canvas = cc._canvas = localCanvas = cc.$(document.createElement("CANVAS"));
this.container = cc.container = localContainer = document.createElement("DIV");
element.appendChild(localContainer);
}
diff --git a/README.mdown b/README.mdown
index 57823c8723..3b13c27fac 100644
--- a/README.mdown
+++ b/README.mdown
@@ -5,36 +5,22 @@ Cocos2d-html5
It incorporates the same high level api as “Cocos2d JS-binding engine” and compatible with Cocos2d-X.
It currently supports canvas and WebGL renderer.
+-------------
+
+#### Cocos2d-html5 has evolved to [Cocos Creator][11], new generation of Cocos game engine with a full featured editor and content creation friendly workflow. It supports all major platforms allowing games to be quickly released for the web, iOS, Android, Windows, Mac, and various mini-game platforms. A pure JavaScript-developed engine runtime is available on the web and mini-game platforms for better performance and smaller packages. On other native platforms, C++ is used to implement the underlying framework, providing greater operational efficiency. The latest repository is maintained in here [Engine of Cocos Creator][9].
+
+-------------
+
Cross Platform
-------------
* Popular browsers: Chrome 14+, Safari 5.0+, IE9+, Firefox 3.5+.
- * Mobile platforms: coming soon.
+ * Mobile platforms: Mobile browsers,Facebook Instant Games and Mini Games.
* Native App: Same piece of code can run on "Cocos2d JS-Binding Engine" without or with little modification.
Documentation
------------------
* Website: [www.cocos2d-x.org][3]
- * API References: [http://www.cocos2d-x.org/wiki/Reference] [4]
-
-
-Installing from [bower][8] (version >=3.4)
-------------------
-
-```shell
-$ bower install cocos2d-html5
-```
-
-Running the tests (version <3)
-------------------
-
-```shell
-$ git clone git://github.com/cocos2d/cocos2d-html5.git
-$ cd cocos2d-html5
-$ git submodule update --init
-$ python -m SimpleHTTPServer
-```
-... and then open a browser and go to `http://localhost:8000/tests`
-
+ * Cocos Creator download: [Cocos Creator][10]
Contact us
------------------
@@ -50,3 +36,6 @@ Contact us
[6]: http://www.twitter.com/cocos2dhtml5 "http://www.twitter.com/cocos2dhtml5"
[7]: http://t.sina.com.cn/cocos2dhtml5 "http://t.sina.com.cn/cocos2dhtml5"
[8]: http://bower.io "http://bower.io"
+[9]: https://github.com/cocos-creator/engine
+[10]: http://cocos2d-x.org/download
+[11]: https://www.cocos.com/en/products#CocosCreator "https://www.cocos.com"
diff --git a/cocos2d/actions/CCActionInterval.js b/cocos2d/actions/CCActionInterval.js
index 74a855748e..905d72b0a2 100644
--- a/cocos2d/actions/CCActionInterval.js
+++ b/cocos2d/actions/CCActionInterval.js
@@ -137,7 +137,7 @@ cc.ActionInterval = cc.FiniteTimeAction.extend(/** @lends cc.ActionInterval# */{
*
* @example
* //example
- * action.easeing(cc.easeIn(3.0));
+ * action.easing(cc.easeIn(3.0));
* @param {Object} easeObj
* @returns {cc.ActionInterval}
*/
@@ -997,7 +997,7 @@ cc.Spawn = cc.ActionInterval.extend(/** @lends cc.Spawn# */{
* Create a spawn action which runs several actions in parallel.
* @function
* @param {Array|cc.FiniteTimeAction}tempArray
- * @return {cc.FiniteTimeAction}
+ * @return {cc.Spawn}
* @example
* // example
* var action = cc.spawn(cc.jumpBy(2, cc.p(300, 0), 50, 4), cc.rotateBy(2, 720));
@@ -1022,7 +1022,7 @@ cc.spawn = function (/*Multiple Arguments*/tempArray) {
* @static
* @deprecated since v3.0
Please use cc.spawn instead.
* @param {Array|cc.FiniteTimeAction}tempArray
- * @return {cc.FiniteTimeAction}
+ * @return {cc.Spawn}
*/
cc.Spawn.create = cc.spawn;
@@ -1083,7 +1083,7 @@ cc.RotateTo = cc.ActionInterval.extend(/** @lends cc.RotateTo# */{
initWithDuration: function (duration, deltaAngleX, deltaAngleY) {
if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) {
this._dstAngleX = deltaAngleX || 0;
- this._dstAngleY = deltaAngleY || this._dstAngleX;
+ this._dstAngleY = deltaAngleY !== undefined ? deltaAngleY : this._dstAngleX;
return true;
}
return false;
@@ -1311,7 +1311,7 @@ cc.RotateBy.create = cc.rotateBy;
* @param {cc.Point|Number} deltaPos
* @param {Number} [deltaY]
* @example
- * var actionTo = cc.moveBy(2, cc.p(windowSize.width - 40, windowSize.height - 40));
+ * var actionBy = cc.moveBy(2, cc.p(windowSize.width - 40, windowSize.height - 40));
*/
cc.MoveBy = cc.ActionInterval.extend(/** @lends cc.MoveBy# */{
_positionDelta: null,
@@ -1430,7 +1430,7 @@ cc.MoveBy = cc.ActionInterval.extend(/** @lends cc.MoveBy# */{
* @return {cc.MoveBy}
* @example
* // example
- * var actionTo = cc.moveBy(2, cc.p(windowSize.width - 40, windowSize.height - 40));
+ * var actionBy = cc.moveBy(2, cc.p(windowSize.width - 40, windowSize.height - 40));
*/
cc.moveBy = function (duration, deltaPos, deltaY) {
return new cc.MoveBy(duration, deltaPos, deltaY);
@@ -1458,7 +1458,7 @@ cc.MoveBy.create = cc.moveBy;
* @param {cc.Point|Number} position
* @param {Number} y
* @example
- * var actionBy = new cc.MoveTo(2, cc.p(80, 80));
+ * var actionTo = new cc.MoveTo(2, cc.p(80, 80));
*/
cc.MoveTo = cc.MoveBy.extend(/** @lends cc.MoveTo# */{
_endPosition: null,
@@ -1524,12 +1524,12 @@ cc.MoveTo = cc.MoveBy.extend(/** @lends cc.MoveTo# */{
* Moving to the specified coordinates.
* @function
* @param {Number} duration duration in seconds
- * @param {cc.Point} position
+ * @param {cc.Point|Number} position
* @param {Number} y
- * @return {cc.MoveBy}
+ * @return {cc.MoveTo}
* @example
* // example
- * var actionBy = cc.moveTo(2, cc.p(80, 80));
+ * var actionTo = cc.moveTo(2, cc.p(80, 80));
*/
cc.moveTo = function (duration, position, y) {
return new cc.MoveTo(duration, position, y);
@@ -1540,9 +1540,9 @@ cc.moveTo = function (duration, position, y) {
* @static
* @deprecated since v3.0
Please use cc.moveTo instead.
* @param {Number} duration duration in seconds
- * @param {cc.Point} position
+ * @param {cc.Point|Number} position
* @param {Number} y
- * @return {cc.MoveBy}
+ * @return {cc.MoveTo}
*/
cc.MoveTo.create = cc.moveTo;
diff --git a/cocos2d/core/CCActionManager.js b/cocos2d/core/CCActionManager.js
index f3c90b46ab..980be114b4 100644
--- a/cocos2d/core/CCActionManager.js
+++ b/cocos2d/core/CCActionManager.js
@@ -30,25 +30,14 @@
* @example
* var element = new cc.HashElement();
*/
-cc.HashElement = cc.Class.extend(/** @lends cc.HashElement# */{
- actions:null,
- target:null, //ccobject
- actionIndex:0,
- currentAction:null, //CCAction
- currentActionSalvaged:false,
- paused:false,
- /**
- * Constructor
- */
- ctor:function () {
- this.actions = [];
- this.target = null;
- this.actionIndex = 0;
- this.currentAction = null; //CCAction
- this.currentActionSalvaged = false;
- this.paused = false;
- }
-});
+cc.HashElement = function () {
+ this.actions = [];
+ this.target = null;
+ this.actionIndex = 0;
+ this.currentAction = null; //CCAction
+ this.paused = false;
+ this.lock = false;
+};
/**
* cc.ActionManager is a class that can manage actions.
@@ -64,10 +53,6 @@ cc.HashElement = cc.Class.extend(/** @lends cc.HashElement# */{
* var mng = new cc.ActionManager();
*/
cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
- _hashTargets:null,
- _arrayTargets:null,
- _currentTarget:null,
- _currentTargetSalvaged:false,
_elementPool: [],
_searchElementByTarget:function (arr, target) {
@@ -82,7 +67,6 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
this._hashTargets = {};
this._arrayTargets = [];
this._currentTarget = null;
- this._currentTargetSalvaged = false;
},
_getElement: function (target, paused) {
@@ -99,8 +83,9 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
element.actions.length = 0;
element.actionIndex = 0;
element.currentAction = null;
- element.currentActionSalvaged = false;
element.paused = false;
+ element.target = null;
+ element.lock = false;
this._elementPool.push(element);
},
@@ -116,7 +101,7 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
if(!action)
throw new Error("cc.ActionManager.addAction(): action must be non-null");
if(!target)
- throw new Error("cc.ActionManager.addAction(): action must be non-null");
+ throw new Error("cc.ActionManager.addAction(): target must be non-null");
//check if the action target already exists
var element = this._hashTargets[target.__instanceId];
@@ -156,15 +141,8 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
return;
var element = this._hashTargets[target.__instanceId];
if (element) {
- if (element.actions.indexOf(element.currentAction) !== -1 && !(element.currentActionSalvaged))
- element.currentActionSalvaged = true;
-
element.actions.length = 0;
- if (this._currentTarget === element && !forceDelete) {
- this._currentTargetSalvaged = true;
- } else {
- this._deleteHashElement(element);
- }
+ this._deleteHashElement(element);
}
},
/** Removes an action given an action reference.
@@ -181,6 +159,9 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
for (var i = 0; i < element.actions.length; i++) {
if (element.actions[i] === action) {
element.actions.splice(i, 1);
+ // update actionIndex in case we are in tick. looping over the actions
+ if (element.actionIndex >= i)
+ element.actionIndex--;
break;
}
}
@@ -291,10 +272,10 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
* @param {Array} targetsToResume
*/
resumeTargets:function(targetsToResume){
- if(!targetsToResume)
+ if (!targetsToResume)
return;
- for(var i = 0 ; i< targetsToResume.length; i++){
+ for (var i = 0; i< targetsToResume.length; i++) {
if(targetsToResume[i])
this.resumeTarget(targetsToResume[i]);
}
@@ -311,9 +292,6 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
_removeActionAtIndex:function (index, element) {
var action = element.actions[index];
- if ((action === element.currentAction) && (!element.currentActionSalvaged))
- element.currentActionSalvaged = true;
-
element.actions.splice(index, 1);
// update actionIndex in case we are in tick. looping over the actions
@@ -321,17 +299,13 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
element.actionIndex--;
if (element.actions.length === 0) {
- if (this._currentTarget === element) {
- this._currentTargetSalvaged = true;
- } else {
- this._deleteHashElement(element);
- }
+ this._deleteHashElement(element);
}
},
_deleteHashElement:function (element) {
var ret = false;
- if (element) {
+ if (element && !element.lock) {
if (this._hashTargets[element.target.__instanceId]) {
delete this._hashTargets[element.target.__instanceId];
var targets = this._arrayTargets;
@@ -356,41 +330,30 @@ cc.ActionManager = cc.Class.extend(/** @lends cc.ActionManager# */{
for (var elt = 0; elt < locTargets.length; elt++) {
this._currentTarget = locTargets[elt];
locCurrTarget = this._currentTarget;
- //this._currentTargetSalvaged = false;
- if (!locCurrTarget.paused) {
+ if (!locCurrTarget.paused && locCurrTarget.actions) {
+ locCurrTarget.lock = true;
// The 'actions' CCMutableArray may change while inside this loop.
- for (locCurrTarget.actionIndex = 0;
- locCurrTarget.actionIndex < (locCurrTarget.actions ? locCurrTarget.actions.length : 0);
- locCurrTarget.actionIndex++) {
+ for (locCurrTarget.actionIndex = 0; locCurrTarget.actionIndex < locCurrTarget.actions.length; locCurrTarget.actionIndex++) {
locCurrTarget.currentAction = locCurrTarget.actions[locCurrTarget.actionIndex];
if (!locCurrTarget.currentAction)
continue;
- locCurrTarget.currentActionSalvaged = false;
//use for speed
locCurrTarget.currentAction.step(dt * ( locCurrTarget.currentAction._speedMethod ? locCurrTarget.currentAction._speed : 1 ) );
- if (locCurrTarget.currentActionSalvaged) {
- // The currentAction told the node to remove it. To prevent the action from
- // accidentally deallocating itself before finishing its step, we retained
- // it. Now that step is done, it's safe to release it.
- locCurrTarget.currentAction = null;//release
- } else if (locCurrTarget.currentAction.isDone()) {
+
+ if (locCurrTarget.currentAction && locCurrTarget.currentAction.isDone()) {
locCurrTarget.currentAction.stop();
var action = locCurrTarget.currentAction;
- // Make currentAction nil to prevent removeAction from salvaging it.
locCurrTarget.currentAction = null;
this.removeAction(action);
}
locCurrTarget.currentAction = null;
}
+ locCurrTarget.lock = false;
}
-
- // elt, at this moment, is still valid
- // so it is safe to ask this here (issue #490)
-
// only delete currentTarget if no actions were scheduled during the cycle (issue #481)
- if (this._currentTargetSalvaged && locCurrTarget.actions.length === 0) {
+ if (locCurrTarget.actions.length === 0) {
this._deleteHashElement(locCurrTarget) && elt--;
}
}
diff --git a/cocos2d/core/CCDirector.js b/cocos2d/core/CCDirector.js
index bfc8481d68..b8a021f43c 100644
--- a/cocos2d/core/CCDirector.js
+++ b/cocos2d/core/CCDirector.js
@@ -136,6 +136,7 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
//action manager
if (cc.ActionManager) {
this._actionManager = new cc.ActionManager();
+ this._scheduler.scheduleUpdate(this._actionManager, cc.Scheduler.PRIORITY_SYSTEM, false);
} else {
this._actionManager = null;
}
@@ -228,7 +229,6 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
//tick before glClear: issue #533
if (!this._paused) {
- this._actionManager.update(this._deltaTime);
this._scheduler.update(this._deltaTime);
cc.eventManager.dispatchEvent(this._eventAfterUpdate);
}
@@ -943,4 +943,4 @@ cc.Director.PROJECTION_CUSTOM = 3;
* @constant
* @type {Number}
*/
-cc.Director.PROJECTION_DEFAULT = cc.Director.PROJECTION_2D;
+cc.Director.PROJECTION_DEFAULT = cc.Director.PROJECTION_3D;
diff --git a/cocos2d/core/CCDrawingPrimitivesCanvas.js b/cocos2d/core/CCDrawingPrimitivesCanvas.js
index ce4c914a85..f94b4ca297 100644
--- a/cocos2d/core/CCDrawingPrimitivesCanvas.js
+++ b/cocos2d/core/CCDrawingPrimitivesCanvas.js
@@ -56,11 +56,9 @@ cc.DrawingPrimitiveCanvas = cc.Class.extend(/** @lends cc.DrawingPrimitiveCanvas
if (!size) {
size = 1;
}
- var locScaleX = cc.view.getScaleX(), locScaleY = cc.view.getScaleY();
- var newPoint = cc.p(point.x * locScaleX, point.y * locScaleY);
var ctx = this._renderContext.getContext();
ctx.beginPath();
- ctx.arc(newPoint.x, -newPoint.y, size * locScaleX, 0, Math.PI * 2, false);
+ ctx.arc(point.x, -point.y, size, 0, Math.PI * 2, false);
ctx.closePath();
ctx.fill();
},
@@ -79,11 +77,11 @@ cc.DrawingPrimitiveCanvas = cc.Class.extend(/** @lends cc.DrawingPrimitiveCanvas
if (!size) {
size = 1;
}
- var locContext = this._renderContext.getContext(),locScaleX = cc.view.getScaleX(), locScaleY = cc.view.getScaleY();
+ var locContext = this._renderContext.getContext();
locContext.beginPath();
for (var i = 0, len = points.length; i < len; i++)
- locContext.arc(points[i].x * locScaleX, -points[i].y * locScaleY, size * locScaleX, 0, Math.PI * 2, false);
+ locContext.arc(points[i].x, -points[i].y, size, 0, Math.PI * 2, false);
locContext.closePath();
locContext.fill();
},
@@ -95,7 +93,7 @@ cc.DrawingPrimitiveCanvas = cc.Class.extend(/** @lends cc.DrawingPrimitiveCanvas
* @param {cc.Point} destination
*/
drawLine:function (origin, destination) {
- var locContext = this._renderContext.getContext(), locScaleX = cc.view.getScaleX(), locScaleY = cc.view.getScaleY();
+ var locContext = this._renderContext.getContext();
locContext.beginPath();
locContext.moveTo(origin.x , -origin.y );
locContext.lineTo(destination.x, -destination.y );
@@ -151,7 +149,6 @@ cc.DrawingPrimitiveCanvas = cc.Class.extend(/** @lends cc.DrawingPrimitiveCanvas
throw new Error("Polygon's point must greater than 2");
var firstPoint = vertices[0], locContext = this._renderContext.getContext();
- var locScaleX = cc.view.getScaleX(), locScaleY = cc.view.getScaleY();
locContext.beginPath();
locContext.moveTo(firstPoint.x , -firstPoint.y );
for (var i = 1, len = vertices.length; i < len; i++)
@@ -189,7 +186,6 @@ cc.DrawingPrimitiveCanvas = cc.Class.extend(/** @lends cc.DrawingPrimitiveCanvas
drawCircle: function (center, radius, angle, segments, drawLineToCenter) {
drawLineToCenter = drawLineToCenter || false;
var locContext = this._renderContext.getContext();
- var locScaleX = cc.view.getScaleX(), locScaleY = cc.view.getScaleY();
locContext.beginPath();
var endAngle = angle - Math.PI * 2;
locContext.arc(0 | (center.x ), 0 | -(center.y ), radius , -angle, -endAngle, false);
@@ -379,7 +375,6 @@ cc.DrawingPrimitiveCanvas = cc.Class.extend(/** @lends cc.DrawingPrimitiveCanvas
drawColorBall:function (ctx, radius, color) {
var wrapper = ctx || this._renderContext;
var context = wrapper.getContext();
- radius *= cc.view.getScaleX();
var colorStr = "rgba(" +(0|color.r) + "," + (0|color.g) + "," + (0|color.b);
var subRadius = radius / 10;
@@ -432,6 +427,6 @@ cc.DrawingPrimitiveCanvas = cc.Class.extend(/** @lends cc.DrawingPrimitiveCanvas
* @param {Number} width
*/
setLineWidth:function (width) {
- this._renderContext.getContext().lineWidth = width * cc.view.getScaleX();
+ this._renderContext.getContext().lineWidth = width;
}
});
\ No newline at end of file
diff --git a/cocos2d/core/CCDrawingPrimitivesWebGL.js b/cocos2d/core/CCDrawingPrimitivesWebGL.js
index f8c9b46d0d..6daa60cb01 100644
--- a/cocos2d/core/CCDrawingPrimitivesWebGL.js
+++ b/cocos2d/core/CCDrawingPrimitivesWebGL.js
@@ -61,6 +61,7 @@ cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL#
_t._shader = cc.shaderCache.programForKey(cc.SHADER_POSITION_UCOLOR);
_t._shader._addUniformLocation(this._colorLocation);
_t._shader._addUniformLocation(this._pointSizeLocation);
+ _t._glProgramState = cc.GLProgramState.getOrCreateWithGLProgram(_t._shader);
_t._initialized = true;
}
@@ -81,7 +82,7 @@ cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL#
this.lazy_init();
var glContext = this._renderContext;
- this._shader.use();
+ this._glProgramState.apply();
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
@@ -110,7 +111,7 @@ cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL#
this.lazy_init();
var glContext = this._renderContext;
- this._shader.use();
+ this._glProgramState.apply();
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
@@ -145,7 +146,7 @@ cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL#
this.lazy_init();
var glContext = this._renderContext;
- this._shader.use();
+ this._glProgramState.apply();
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
@@ -200,7 +201,7 @@ cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL#
this.lazy_init();
var glContext = this._renderContext;
- this._shader.use();
+ this._glProgramState.apply();
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
@@ -231,7 +232,7 @@ cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL#
this.setDrawColor(color.r, color.g, color.b, color.a);
var glContext = this._renderContext;
- this._shader.use();
+ this._glProgramState.apply();
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
@@ -279,7 +280,7 @@ cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL#
vertices[(segments + 1) * 2 + 1] = center.y;
var glContext = this._renderContext;
- this._shader.use();
+ this._glProgramState.apply();
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
@@ -317,7 +318,7 @@ cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL#
vertices[segments * 2 + 1] = destination.y;
var glContext = this._renderContext;
- this._shader.use();
+ this._glProgramState.apply();
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
@@ -356,7 +357,7 @@ cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL#
vertices[segments * 2 + 1] = destination.y;
var glContext = this._renderContext;
- this._shader.use();
+ this._glProgramState.apply();
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
@@ -416,7 +417,7 @@ cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL#
}
var glContext = this._renderContext;
- this._shader.use();
+ this._glProgramState.apply();
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
diff --git a/cocos2d/core/CCScheduler.js b/cocos2d/core/CCScheduler.js
index 0c75dc15af..1504bd70c0 100644
--- a/cocos2d/core/CCScheduler.js
+++ b/cocos2d/core/CCScheduler.js
@@ -385,7 +385,7 @@ cc.Scheduler = cc.Class.extend(/** @lends cc.Scheduler# */{
_removeUpdateFromHash:function (entry) {
var self = this;
- element = self._hashForUpdates[entry.target.__instanceId];
+ var element = self._hashForUpdates[entry.target.__instanceId];
if (element) {
// Remove list entry from list
var list = element.list, listEntry = element.entry;
diff --git a/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js b/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js
index 8fce00f8da..5810d00794 100644
--- a/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js
+++ b/cocos2d/core/base-nodes/CCAtlasNodeWebGLRenderCmd.js
@@ -68,8 +68,7 @@
this._matrix.mat[5] = wt.d;
this._matrix.mat[13] = wt.ty;
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix);
+ this._glProgramState.apply(this._matrix);
cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
if (this._uniformColor && this._colorF32Array) {
diff --git a/cocos2d/core/base-nodes/CCNode.js b/cocos2d/core/base-nodes/CCNode.js
index 98d5ccc828..9d3e6f15e5 100644
--- a/cocos2d/core/base-nodes/CCNode.js
+++ b/cocos2d/core/base-nodes/CCNode.js
@@ -306,6 +306,8 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
* @param {Number} localZOrder
*/
setLocalZOrder: function (localZOrder) {
+ if (localZOrder === this._localZOrder)
+ return;
if (this._parent)
this._parent.reorderChild(this, localZOrder);
else
@@ -1365,9 +1367,6 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
cc.log(cc._LogInfos.Node_reorderChild_2);
return;
}
- if (zOrder === child.zIndex) {
- return;
- }
cc.renderer.childrenOrderDirty = this._reorderChildDirty = true;
child.arrivalOrder = cc.s_globalOrderOfArrival;
cc.s_globalOrderOfArrival++;
@@ -2240,6 +2239,14 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
this._renderCmd.setShaderProgram(newShaderProgram);
},
+ setGLProgramState: function (glProgramState) {
+ this._renderCmd.setGLProgramState(glProgramState);
+ },
+
+ getGLProgramState: function () {
+ return this._renderCmd.getGLProgramState();
+ },
+
/**
* Returns the state of OpenGL server side.
* @function
diff --git a/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js b/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js
index 6b4d170ce1..43c46d0f7f 100644
--- a/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js
+++ b/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js
@@ -529,7 +529,23 @@ cc.Node.RenderCmd.prototype = {
if (locFlag & dirtyFlags.orderDirty)
this._dirtyFlag &= ~dirtyFlags.orderDirty;
- }
+ },
+
+ setShaderProgram: function (shaderProgram) {
+ //do nothing.
+ },
+
+ getShaderProgram: function () {
+ return null;
+ },
+
+ getGLProgramState: function () {
+ return null;
+ },
+
+ setGLProgramState: function (glProgramState) {
+ // do nothing
+ },
};
cc.Node.RenderCmd.prototype.originTransform = cc.Node.RenderCmd.prototype.transform;
@@ -623,14 +639,6 @@ cc.Node.RenderCmd.prototype._originSyncStatus = cc.Node.RenderCmd.prototype._syn
}
};
- proto.setShaderProgram = function (shaderProgram) {
- //do nothing.
- };
-
- proto.getShaderProgram = function () {
- return null;
- };
-
//util functions
cc.Node.CanvasRenderCmd._getCompositeOperationByBlendFunc = function (blendFunc) {
if (!blendFunc)
diff --git a/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js b/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js
index 62e469800e..7680017273 100644
--- a/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js
+++ b/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js
@@ -27,7 +27,7 @@
this._node = renderable;
this._anchorPointInPoints = {x: 0, y: 0};
this._displayedColor = cc.color(255, 255, 255, 255);
- this._shaderProgram = null;
+ this._glProgramState = null;
};
var proto = cc.Node.WebGLRenderCmd.prototype = Object.create(cc.Node.RenderCmd.prototype);
@@ -38,10 +38,28 @@
};
proto.setShaderProgram = function (shaderProgram) {
- this._shaderProgram = shaderProgram;
+ this._glProgramState = cc.GLProgramState.getOrCreateWithGLProgram(shaderProgram);
};
proto.getShaderProgram = function () {
- return this._shaderProgram;
+ return this._glProgramState ? this._glProgramState.getGLProgram() : null;
};
+
+ proto.getGLProgramState = function () {
+ return this._glProgramState;
+ };
+
+ proto.setGLProgramState = function (glProgramState) {
+ this._glProgramState = glProgramState;
+ };
+
+ // Use a property getter/setter for backwards compatability, and
+ // to ease the transition from using glPrograms directly, to
+ // using glProgramStates.
+ Object.defineProperty(proto, '_shaderProgram', {
+ set: function (value) { this.setShaderProgram(value); },
+ get: function () { return this.getShaderProgram(); }
+ });
+ /** @expose */
+ proto._shaderProgram;
})();
diff --git a/cocos2d/core/event-manager/CCEventListener.js b/cocos2d/core/event-manager/CCEventListener.js
index 06e5bd4eee..c970c43fdf 100644
--- a/cocos2d/core/event-manager/CCEventListener.js
+++ b/cocos2d/core/event-manager/CCEventListener.js
@@ -277,15 +277,16 @@ cc.EventListener.CUSTOM = 8;
cc._EventListenerCustom = cc.EventListener.extend({
_onCustomEvent: null,
- ctor: function (listenerId, callback) {
+ ctor: function (listenerId, callback, target) {
this._onCustomEvent = callback;
- var selfPointer = this;
- var listener = function (event) {
- if (selfPointer._onCustomEvent !== null)
- selfPointer._onCustomEvent(event);
- };
+ this._target = target;
- cc.EventListener.prototype.ctor.call(this, cc.EventListener.CUSTOM, listenerId, listener);
+ cc.EventListener.prototype.ctor.call(this, cc.EventListener.CUSTOM, listenerId, this._callback);
+ },
+
+ _callback: function (event) {
+ if (this._onCustomEvent !== null)
+ this._onCustomEvent.call(this._target, event);
},
checkAvailable: function () {
@@ -308,31 +309,31 @@ cc._EventListenerMouse = cc.EventListener.extend({
onMouseScroll: null,
ctor: function () {
- var selfPointer = this;
- var listener = function (event) {
- var eventType = cc.EventMouse;
- switch (event._eventType) {
- case eventType.DOWN:
- if (selfPointer.onMouseDown)
- selfPointer.onMouseDown(event);
- break;
- case eventType.UP:
- if (selfPointer.onMouseUp)
- selfPointer.onMouseUp(event);
- break;
- case eventType.MOVE:
- if (selfPointer.onMouseMove)
- selfPointer.onMouseMove(event);
- break;
- case eventType.SCROLL:
- if (selfPointer.onMouseScroll)
- selfPointer.onMouseScroll(event);
- break;
- default:
- break;
- }
- };
- cc.EventListener.prototype.ctor.call(this, cc.EventListener.MOUSE, cc._EventListenerMouse.LISTENER_ID, listener);
+ cc.EventListener.prototype.ctor.call(this, cc.EventListener.MOUSE, cc._EventListenerMouse.LISTENER_ID, this._callback);
+ },
+
+ _callback: function (event) {
+ var eventType = cc.EventMouse;
+ switch (event._eventType) {
+ case eventType.DOWN:
+ if (this.onMouseDown)
+ this.onMouseDown(event);
+ break;
+ case eventType.UP:
+ if (this.onMouseUp)
+ this.onMouseUp(event);
+ break;
+ case eventType.MOVE:
+ if (this.onMouseMove)
+ this.onMouseMove(event);
+ break;
+ case eventType.SCROLL:
+ if (this.onMouseScroll)
+ this.onMouseScroll(event);
+ break;
+ default:
+ break;
+ }
},
clone: function () {
@@ -501,11 +502,12 @@ cc._EventListenerFocus = cc.EventListener.extend({
},
onFocusChanged: null,
ctor: function(){
- var listener = function(event){
- if(this.onFocusChanged)
- this.onFocusChanged(event._widgetLoseFocus, event._widgetGetFocus);
- };
- cc.EventListener.prototype.ctor.call(this, cc.EventListener.FOCUS, cc._EventListenerFocus.LISTENER_ID, listener);
+ cc.EventListener.prototype.ctor.call(this, cc.EventListener.FOCUS, cc._EventListenerFocus.LISTENER_ID, this._callback);
+ },
+ _callback: function (event) {
+ if (this.onFocusChanged) {
+ this.onFocusChanged(event._widgetLoseFocus, event._widgetGetFocus);
+ }
}
});
diff --git a/cocos2d/core/event-manager/CCEventManager.js b/cocos2d/core/event-manager/CCEventManager.js
index 890ba5bf7c..7f54f03939 100644
--- a/cocos2d/core/event-manager/CCEventManager.js
+++ b/cocos2d/core/event-manager/CCEventManager.js
@@ -258,8 +258,8 @@ cc.eventManager = /** @lends cc.eventManager# */{
if (!this._inDispatch) {
listeners.clear();
- delete this._listenersMap[listenerID];
}
+ delete this._listenersMap[listenerID];
}
var locToAddedListeners = this._toAddedListeners, listener;
@@ -751,8 +751,8 @@ cc.eventManager = /** @lends cc.eventManager# */{
* @param {function} callback
* @return {cc.EventListener} the generated event. Needed in order to remove the event from the dispatcher
*/
- addCustomListener: function (eventName, callback) {
- var listener = new cc._EventListenerCustom(eventName, callback);
+ addCustomListener: function (eventName, callback, target) {
+ var listener = new cc._EventListenerCustom(eventName, callback, target);
this.addListener(listener, 1);
return listener;
},
diff --git a/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js b/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js
index 51fb3888b4..44c8f1866f 100644
--- a/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js
+++ b/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js
@@ -24,13 +24,25 @@ cc.LabelTTF._textBaseline = ["top", "middle", "bottom"];
//check the first character
cc.LabelTTF.wrapInspection = true;
-//Support: English French German
-//Other as Oriental Language
-cc.LabelTTF._wordRex = /([a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]+|\S)/;
-cc.LabelTTF._symbolRex = /^[!,.:;}\]%\?>、‘“》?。,!]/;
-cc.LabelTTF._lastWordRex = /([a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]+|\S)$/;
-cc.LabelTTF._lastEnglish = /[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]+$/;
-cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
+// These regular expressions consider a word any sequence of characters
+// from these Unicode (sub)blocks:
+// - Basic Latin (letters and numbers, plus the hypen-minus '-')
+// - Latin-1 Supplement (accentuated letters and ¿¡ only)
+// - Latin Extended-A (complete)
+// - Latin Extended-B (complete)
+// - IPA Extensions (complete)
+// - Spacing Modifier Letters (complete)
+// - Combining Diacritical Marks (Combining Grapheme Joiner excluded)
+// - Greek and Coptic (complete, including reserved code points)
+// - Cyrillic (complete)
+// - Cyrillic Supplement (complete)
+// - General Punctuation (Non-Breaking Hyphen* [U+2011] and quotation marks)
+// * Note that Hyphen [U+2010] is considered a word boundary.
+cc.LabelTTF._wordRex = /([a-zA-Z0-9\-¿¡«À-ÖØ-öø-ʯ\u0300-\u034e\u0350-\u036FͰ-ԯ\u2011‵-‷‹⁅]+|\S)/;
+cc.LabelTTF._symbolRex = /^[!,.:;}\]%\?>、‘“》»?。,!\u2010′-‴›‼⁆⁇-⁉]/;
+cc.LabelTTF._lastWordRex = /([a-zA-Z0-9\-¿¡«À-ÖØ-öø-ʯ\u0300-\u034e\u0350-\u036FͰ-ԯ\u2011‵-‷‹⁅]+|\S)$/;
+cc.LabelTTF._lastEnglish = /[a-zA-Z0-9\-¿¡«À-ÖØ-öø-ʯ\u0300-\u034e\u0350-\u036FͰ-ԯ\u2011‵-‷‹⁅]+$/;
+cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9\-¿¡«À-ÖØ-öø-ʯ\u0300-\u034e\u0350-\u036FͰ-ԯ\u2011‵-‷‹⁅]/;
(function () {
cc.LabelTTF.RenderCmd = function () {
@@ -375,8 +387,10 @@ cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
var locStrLen = this._strings.length;
for (var i = 0; i < locStrLen; i++) {
var line = this._strings[i];
- if (locStrokeEnabled)
+ if (locStrokeEnabled) {
+ context.lineJoin = 'round';
context.strokeText(line, xOffset, yOffsetArray[i]);
+ }
context.fillText(line, xOffset, yOffsetArray[i]);
}
cc.g_NumberOfDraws++;
@@ -418,7 +432,10 @@ cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
if (node._string.length === 0) {
locLabelCanvas.width = 1;
locLabelCanvas.height = locContentSize.height || 1;
- node._texture && node._texture.handleLoadedTexture();
+ if (node._texture) {
+ node._texture._htmlElementObj = this._labelCanvas;
+ node._texture.handleLoadedTexture();
+ }
node.setTextureRect(cc.rect(0, 0, 1, locContentSize.height));
return true;
}
@@ -432,7 +449,10 @@ cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/;
if (flag) locContext.clearRect(0, 0, width, height);
this._saveStatus();
this._drawTTFInCanvas(locContext);
- node._texture && node._texture.handleLoadedTexture();
+ if (node._texture) {
+ node._texture._htmlElementObj = this._labelCanvas;
+ node._texture.handleLoadedTexture();
+ }
node.setTextureRect(cc.rect(0, 0, width, height));
return true;
};
diff --git a/cocos2d/core/layers/CCLayerWebGLRenderCmd.js b/cocos2d/core/layers/CCLayerWebGLRenderCmd.js
index 544428278b..4acf7f22d6 100644
--- a/cocos2d/core/layers/CCLayerWebGLRenderCmd.js
+++ b/cocos2d/core/layers/CCLayerWebGLRenderCmd.js
@@ -136,8 +136,7 @@
this._dataDirty = false;
}
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix);
+ this._glProgramState.apply(this._matrix);
cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
@@ -302,8 +301,7 @@
}
//draw gradient layer
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix);
+ this._glProgramState.apply(this._matrix);
cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst);
gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
diff --git a/cocos2d/core/platform/CCClass.js b/cocos2d/core/platform/CCClass.js
index 6b7a2e8043..be34ad92eb 100644
--- a/cocos2d/core/platform/CCClass.js
+++ b/cocos2d/core/platform/CCClass.js
@@ -140,19 +140,19 @@ cc.inject = function (srcPrototype, destPrototype) {
* @namespace
* @name ClassManager
*/
-var ClassManager = {
- id : (0|(Math.random()*998)),
+var ClassManager = function () {
+ var id = (0|(Math.random()*998));
+ var instanceId = (0|(Math.random()*998));
- instanceId : (0|(Math.random()*998)),
-
- getNewID : function(){
- return this.id++;
- },
+ this.getNewID = function () {
+ return id++;
+ };
- getNewInstanceId : function(){
- return this.instanceId++;
- }
+ this.getNewInstanceId = function () {
+ return instanceId++;
+ };
};
+var classManager = new ClassManager();
/* Managed JavaScript Inheritance
* Based on John Resig's Simple JavaScript Inheritance http://ejohn.org/blog/simple-javascript-inheritance/
@@ -192,7 +192,7 @@ var ClassManager = {
var Class;
if (cc.game.config && cc.game.config[cc.game.CONFIG_KEY.exposeClassName]) {
var constructor = "(function " + (props._className || "Class") + " (arg0, arg1, arg2, arg3, arg4, arg5) {\n";
- constructor += " this.__instanceId = ClassManager.getNewInstanceId();\n";
+ constructor += " this.__instanceId = classManager.getNewInstanceId();\n";
constructor += " if (this.ctor) {\n";
constructor += " switch (arguments.length) {\n";
constructor += " case 0: this.ctor(); break;\n";
@@ -208,7 +208,7 @@ var ClassManager = {
}
else {
Class = function (arg0, arg1, arg2, arg3, arg4) {
- this.__instanceId = ClassManager.getNewInstanceId();
+ this.__instanceId = classManager.getNewInstanceId();
if (this.ctor) {
switch (arguments.length) {
case 0: this.ctor(); break;
@@ -223,7 +223,7 @@ var ClassManager = {
};
}
- desc.value = ClassManager.getNewID();
+ desc.value = classManager.getNewID();
Object.defineProperty(prototype, '__pid', desc);
// Populate our constructed prototype object
diff --git a/cocos2d/core/platform/CCConfig.js b/cocos2d/core/platform/CCConfig.js
index 4fb22921f8..b4795155ed 100644
--- a/cocos2d/core/platform/CCConfig.js
+++ b/cocos2d/core/platform/CCConfig.js
@@ -31,7 +31,7 @@
* @type {String}
* @name cc.ENGINE_VERSION
*/
-window["CocosEngine"] = cc.ENGINE_VERSION = "Cocos2d-JS v3.15";
+window["CocosEngine"] = cc.ENGINE_VERSION = "Cocos2d-JS v3.17";
/**
*
diff --git a/cocos2d/core/platform/CCEGLView.js b/cocos2d/core/platform/CCEGLView.js index 6093dc0b04..f91e54b8b8 100755 --- a/cocos2d/core/platform/CCEGLView.js +++ b/cocos2d/core/platform/CCEGLView.js @@ -184,6 +184,12 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{ _t._rpFixedWidth = new cc.ResolutionPolicy(_strategyer.EQUAL_TO_FRAME, _strategy.FIXED_WIDTH); _t._targetDensityDPI = cc.DENSITYDPI_HIGH; + + if (sys.isMobile) { + window.addEventListener('orientationchange', this._orientationChange); + } else { + this._orientationChanging = false; + } }, // Resize helper functions @@ -276,14 +282,12 @@ cc.EGLView = cc.Class.extend(/** @lends cc.view# */{ if (!this.__resizeWithBrowserSize) { this.__resizeWithBrowserSize = true; window.addEventListener('resize', this._resizeEvent); - window.addEventListener('orientationchange', this._orientationChange); } } else { //disable if (this.__resizeWithBrowserSize) { this.__resizeWithBrowserSize = false; window.removeEventListener('resize', this._resizeEvent); - window.removeEventListener('orientationchange', this._orientationChange); } } }, diff --git a/cocos2d/core/platform/CCInputExtension.js b/cocos2d/core/platform/CCInputExtension.js index 6f780104b1..e61f58459a 100644 --- a/cocos2d/core/platform/CCInputExtension.js +++ b/cocos2d/core/platform/CCInputExtension.js @@ -39,10 +39,12 @@ _p.setAccelerometerEnabled = function(isEnable){ var scheduler = cc.director.getScheduler(); if(_t._accelEnabled){ _t._accelCurTime = 0; + _t._registerAccelerometerEvent(); scheduler.scheduleUpdate(_t); } else { _t._accelCurTime = 0; - scheduler.scheduleUpdate(_t); + _t._unregisterAccelerometerEvent(); + scheduler.unscheduleUpdate(_t); } }; @@ -85,7 +87,14 @@ _p._registerAccelerometerEvent = function(){ _t._minus = -1; } - w.addEventListener(_deviceEventType, _t.didAccelerate.bind(_t), false); + _t.didAccelerateCallback = _t.didAccelerate.bind(_t); + w.addEventListener(_deviceEventType, _t.didAccelerateCallback, false); +}; + +_p._unregisterAccelerometerEvent = function () { + this._acceleration = null; + var _deviceEventType = (this._accelDeviceEvent === window.DeviceMotionEvent) ? "devicemotion" : "deviceorientation"; + window.removeEventListener(_deviceEventType, this.didAccelerateCallback, false); }; _p.didAccelerate = function (eventData) { diff --git a/cocos2d/core/platform/CCInputManager.js b/cocos2d/core/platform/CCInputManager.js index 382b1f86ed..270c535c7d 100644 --- a/cocos2d/core/platform/CCInputManager.js +++ b/cocos2d/core/platform/CCInputManager.js @@ -601,7 +601,7 @@ cc.inputManager = /** @lends cc.inputManager# */{ this._registerKeyboardEvent(); //register Accelerometer event - this._registerAccelerometerEvent(); + // this._registerAccelerometerEvent(); this._isRegisterEvent = true; }, @@ -609,6 +609,10 @@ cc.inputManager = /** @lends cc.inputManager# */{ _registerKeyboardEvent: function () { }, + /** + * Register Accelerometer event + * @function + */ _registerAccelerometerEvent: function () { }, diff --git a/cocos2d/core/platform/CCLoaders.js b/cocos2d/core/platform/CCLoaders.js index 69c8e9430f..16749a0949 100644 --- a/cocos2d/core/platform/CCLoaders.js +++ b/cocos2d/core/platform/CCLoaders.js @@ -48,15 +48,19 @@ cc._imgLoader = { load: function (realUrl, url, res, cb) { var callback; if (cc.loader.isLoading(realUrl)) { - callback = cb; + callback = function (err, img) { + if (err) + return cb(err); + var tex = cc.textureCache.getTextureForKey(url) || cc.textureCache.handleLoadedTexture(url, img); + cb(null, tex); + }; } else { callback = function (err, img) { if (err) return cb(err); - cc.loader.cache[url] = img; - cc.textureCache.handleLoadedTexture(url); - cb(null, img); + var tex = cc.textureCache.handleLoadedTexture(url, img); + cb(null, tex); }; } cc.loader.loadImg(realUrl, callback); diff --git a/cocos2d/core/platform/CCMacro.js b/cocos2d/core/platform/CCMacro.js index a89331c9f1..a52958c3dc 100644 --- a/cocos2d/core/platform/CCMacro.js +++ b/cocos2d/core/platform/CCMacro.js @@ -175,7 +175,7 @@ cc.nodeDrawSetup = function (node) { //cc.glEnable(node._glServerState); if (node._shaderProgram) { //cc._renderContext.useProgram(node._shaderProgram._programObj); - node._shaderProgram.use(); + node._glProgramState.apply(); node._shaderProgram.setUniformForModelViewAndProjectionMatrixWithMat4(); } }; @@ -499,6 +499,13 @@ cc.ORIENTATION_AUTO = 3; */ cc.CONCURRENCY_HTTP_REQUEST_COUNT = cc.sys.isMobile ? 20 : 0; +/** + * The maximum vertex count for a single batched draw call. + * @constant + * @type Number + */ +cc.BATCH_VERTEX_COUNT = 2000; + // ------------------- vertex attrib flags ----------------------------- /** diff --git a/cocos2d/core/renderer/RendererWebGL.js b/cocos2d/core/renderer/RendererWebGL.js index f7616a5a36..d0655f6f28 100644 --- a/cocos2d/core/renderer/RendererWebGL.js +++ b/cocos2d/core/renderer/RendererWebGL.js @@ -33,8 +33,8 @@ var _batchedInfo = { blendSrc: null, // The batched blend destination, all batching element should have the same blend destination blendDst: null, - // The batched shader, all batching element should have the same shader - shader: null + // The batched gl program state, all batching element should have the same state + glProgramState: null }, _batchBroken = false, @@ -129,7 +129,7 @@ return { _cacheToBufferCmds: {}, // an array saves the renderer commands need for cache to other canvas _cacheInstanceIds: [], _currentID: 0, - _clearColor: cc.color(), //background color,default BLACK + _clearColor: cc.color(0, 0, 0, 255), //background color,default BLACK init: function () { var gl = cc._renderContext; @@ -138,7 +138,7 @@ return { this.mat4Identity = new cc.math.Matrix4(); this.mat4Identity.identity(); - initQuadBuffer(2000); + initQuadBuffer(cc.BATCH_VERTEX_COUNT); if (cc.sys.os === cc.sys.OS_IOS) { _IS_IOS = true; } @@ -313,18 +313,23 @@ return { _batchingSize += increment; }, - _updateBatchedInfo: function (texture, blendFunc, shaderProgram) { - if (texture) { + _updateBatchedInfo: function (texture, blendFunc, glProgramState) { + if (texture !== _batchedInfo.texture || + blendFunc.src !== _batchedInfo.blendSrc || + blendFunc.dst !== _batchedInfo.blendDst || + glProgramState !== _batchedInfo.glProgramState) { + // Draw batched elements + this._batchRendering(); + // Update _batchedInfo _batchedInfo.texture = texture; - } - - if (blendFunc) { _batchedInfo.blendSrc = blendFunc.src; _batchedInfo.blendDst = blendFunc.dst; - } + _batchedInfo.glProgramState = glProgramState; - if (shaderProgram) { - _batchedInfo.shader = shaderProgram; + return true; + } + else { + return false; } }, @@ -339,60 +344,29 @@ return { // Check batching var node = cmd._node; - var texture = node._texture || (node._spriteFrame ? node._spriteFrame._texture : null); + var texture = node._texture || (node._spriteFrame && node._spriteFrame._texture); var blendSrc = node._blendFunc.src; var blendDst = node._blendFunc.dst; - var shader = cmd._shaderProgram; + var glProgramState = cmd._glProgramState; if (_batchBroken || _batchedInfo.texture !== texture || _batchedInfo.blendSrc !== blendSrc || _batchedInfo.blendDst !== blendDst || - _batchedInfo.shader !== shader) { + _batchedInfo.glProgramState !== glProgramState) { // Draw batched elements this._batchRendering(); // Update _batchedInfo _batchedInfo.texture = texture; _batchedInfo.blendSrc = blendSrc; _batchedInfo.blendDst = blendDst; - _batchedInfo.shader = shader; + _batchedInfo.glProgramState = glProgramState; _batchBroken = false; } // Upload vertex data var len = cmd.uploadData(_vertexDataF32, _vertexDataUI32, _batchingSize * _sizePerVertex); if (len > 0) { - var i, curr, type = cmd.vertexType || VertexType.QUAD; - switch (type) { - case VertexType.QUAD: - for (i = 0; i < len; i += 4) { - curr = _batchingSize + i; - _indexData[_indexSize++] = curr + 0; - _indexData[_indexSize++] = curr + 1; - _indexData[_indexSize++] = curr + 2; - _indexData[_indexSize++] = curr + 1; - _indexData[_indexSize++] = curr + 2; - _indexData[_indexSize++] = curr + 3; - } - break; - case VertexType.TRIANGLE: - _pureQuad = false; - for (i = 0; i < len; i += 3) { - curr = _batchingSize + i; - _indexData[_indexSize++] = curr + 0; - _indexData[_indexSize++] = curr + 1; - _indexData[_indexSize++] = curr + 2; - } - break; - case VertexType.CUSTOM: - _pureQuad = false; - if (cmd.uploadIndexData) { - _indexSize += cmd.uploadIndexData(_indexData, _indexSize, _batchingSize); - } - break; - default: - return; - } - _batchingSize += len; + this._increaseBatchingSize(len, cmd.vertexType); } }, @@ -403,12 +377,12 @@ return { var gl = cc._renderContext; var texture = _batchedInfo.texture; - var shader = _batchedInfo.shader; + var glProgramState = _batchedInfo.glProgramState; var uploadAll = _batchingSize > _maxVertexSize * 0.5; - if (shader) { - shader.use(); - shader._updateProjectionUniform(); + if (glProgramState) { + glProgramState.apply(); + glProgramState.getGLProgram()._updateProjectionUniform(); } cc.glBlendFunc(_batchedInfo.blendSrc, _batchedInfo.blendDst); diff --git a/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js b/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js index 4a543a616c..51ea5024cb 100644 --- a/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js +++ b/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js @@ -298,7 +298,7 @@ proto.uploadData = function (f32buffer, ui32buffer, vertexDataOffset) { var node = this._node, locTexture = node._texture; if (!(locTexture && locTexture._textureLoaded && node._rect.width && node._rect.height) || !this._displayedOpacity) - return false; + return 0; // Fill in vertex data with quad information (4 vertices for sprite) var opacity = this._displayedOpacity; diff --git a/cocos2d/core/textures/CCTexture2D.js b/cocos2d/core/textures/CCTexture2D.js index cd0a9ff153..b69d83cfd9 100644 --- a/cocos2d/core/textures/CCTexture2D.js +++ b/cocos2d/core/textures/CCTexture2D.js @@ -190,11 +190,8 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { */ handleLoadedTexture: function () { var self = this; - if (self._textureLoaded) return; if (!self._htmlElementObj) { - var img = cc.loader.getRes(self.url); - if (!img) return; - self.initWithElement(img); + return; } var locElement = self._htmlElementObj; @@ -229,6 +226,7 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { }, releaseTexture: function () { + this._htmlElementObj = null; cc.loader.release(this.url); }, diff --git a/cocos2d/core/textures/CCTextureCache.js b/cocos2d/core/textures/CCTextureCache.js index 2099565eb3..5e59c2f83c 100644 --- a/cocos2d/core/textures/CCTextureCache.js +++ b/cocos2d/core/textures/CCTextureCache.js @@ -279,11 +279,11 @@ cc.textureCache = /** @lends cc.textureCache# */{ var selTexture = locTextures[key]; count++; if (selTexture.getHtmlElementObj() instanceof HTMLImageElement) - cc.log(cc._LogInfos.textureCache_dumpCachedTextureInfo, key, selTexture.getHtmlElementObj().src, selTexture.pixelsWidth, selTexture.pixelsHeight); + cc.log(cc._LogInfos.textureCache_dumpCachedTextureInfo, key, selTexture.getHtmlElementObj().src, selTexture.getPixelsWide(), selTexture.getPixelsHigh()); else { - cc.log(cc._LogInfos.textureCache_dumpCachedTextureInfo_2, key, selTexture.pixelsWidth, selTexture.pixelsHeight); + cc.log(cc._LogInfos.textureCache_dumpCachedTextureInfo_2, key, selTexture.getPixelsWide(), selTexture.getPixelsHigh()); } - totalBytes += selTexture.pixelsWidth * selTexture.pixelsHeight * 4; + totalBytes += selTexture.getPixelsWide() * selTexture.getPixelsHigh() * 4; } var locTextureColorsCache = this._textureColorsCache; @@ -313,7 +313,7 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { var _p = cc.textureCache; - _p.handleLoadedTexture = function (url) { + _p.handleLoadedTexture = function (url, img) { var locTexs = this._textures; //remove judge var tex = locTexs[url]; @@ -321,7 +321,9 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { tex = locTexs[url] = new cc.Texture2D(); tex.url = url; } + tex.initWithElement(img); tex.handleLoadedTexture(); + return tex; }; /** @@ -365,12 +367,7 @@ cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { if (err) return cb && cb.call(target, err); - if (!cc.loader.cache[url]) { - cc.loader.cache[url] = img; - } - cc.textureCache.handleLoadedTexture(url); - - var texResult = locTexs[url]; + var texResult = cc.textureCache.handleLoadedTexture(url, img); cb && cb.call(target, texResult); }); diff --git a/cocos2d/core/textures/TexturesWebGL.js b/cocos2d/core/textures/TexturesWebGL.js index bcec5bfb53..2dfe145e56 100644 --- a/cocos2d/core/textures/TexturesWebGL.js +++ b/cocos2d/core/textures/TexturesWebGL.js @@ -83,6 +83,7 @@ cc._tmp.WebGLTexture2D = function () { releaseTexture: function () { if (this._webTextureObj) cc._renderContext.deleteTexture(this._webTextureObj); + this._htmlElementObj = null; cc.loader.release(this.url); }, @@ -339,8 +340,8 @@ cc._tmp.WebGLTexture2D = function () { point.x, height + point.y, 0.0, width + point.x, height + point.y, 0.0]; - self._shaderProgram.use(); - self._shaderProgram.setUniformsForBuiltins(); + self._glProgramState.apply(); + self._glProgramState._glprogram.setUniformsForBuiltins(); cc.glBindTexture2D(self); @@ -369,8 +370,8 @@ cc._tmp.WebGLTexture2D = function () { rect.x, rect.y + rect.height, /*0.0,*/ rect.x + rect.width, rect.y + rect.height /*0.0*/]; - self._shaderProgram.use(); - self._shaderProgram.setUniformsForBuiltins(); + self._glProgramState.apply(); + self._glProgramState._glprogram.setUniformsForBuiltins(); cc.glBindTexture2D(self); @@ -457,11 +458,8 @@ cc._tmp.WebGLTexture2D = function () { // Not sure about this ! Some texture need to be updated even after loaded if (!cc.game._rendererInitialized) return; - if (!self._htmlElementObj) { - var img = cc.loader.getRes(self.url); - if (!img) return; - self.initWithElement(img); - } + if (!self._htmlElementObj) + return; if (!self._htmlElementObj.width || !self._htmlElementObj.height) return; @@ -498,6 +496,9 @@ cc._tmp.WebGLTexture2D = function () { self._hasPremultipliedAlpha = premultiplied; self._hasMipmaps = false; + if (window.ENABLE_IMAEG_POOL) { + self._htmlElementObj = null; + } //dispatch load event to listener. self.dispatchEvent("load"); @@ -854,7 +855,7 @@ cc._tmp.WebGLTextureAtlas = function () { cc._tmp.WebGLTextureCache = function () { var _p = cc.textureCache; - _p.handleLoadedTexture = function (url) { + _p.handleLoadedTexture = function (url, img) { var locTexs = this._textures, tex, ext; //remove judge(webgl) if (!cc.game._rendererInitialized) { @@ -865,6 +866,7 @@ cc._tmp.WebGLTextureCache = function () { tex = locTexs[url] = new cc.Texture2D(); tex.url = url; } + tex.initWithElement(img); ext = cc.path.extname(url); if (ext === ".png") { tex.handleLoadedTexture(true); @@ -872,6 +874,7 @@ cc._tmp.WebGLTextureCache = function () { else { tex.handleLoadedTexture(); } + return tex; }; /** @@ -917,12 +920,7 @@ cc._tmp.WebGLTextureCache = function () { if (err) return cb && cb.call(target, err); - if (!cc.loader.cache[url]) { - cc.loader.cache[url] = img; - } - cc.textureCache.handleLoadedTexture(url); - - var texResult = locTexs[url]; + var texResult = cc.textureCache.handleLoadedTexture(url, img); cb && cb.call(target, texResult); }); diff --git a/cocos2d/core/utils/BinaryLoader.js b/cocos2d/core/utils/BinaryLoader.js index 7127b1279c..46b82b65cf 100644 --- a/cocos2d/core/utils/BinaryLoader.js +++ b/cocos2d/core/utils/BinaryLoader.js @@ -37,6 +37,7 @@ cc.loader.loadBinary = function (url, cb) { var xhr = this.getXMLHttpRequest(), errInfo = "load " + url + " failed!"; xhr.open("GET", url, true); + xhr.responseType = 'arraybuffer'; if (cc.loader.loadBinary._IEFilter) { // IE-specific logic here xhr.setRequestHeader("Accept-Charset", "x-user-defined"); @@ -49,7 +50,7 @@ cc.loader.loadBinary = function (url, cb) { } else { if (xhr.overrideMimeType) xhr.overrideMimeType("text\/plain; charset=x-user-defined"); xhr.onload = function () { - xhr.readyState === 4 && xhr.status === 200 ? cb(null, self._str2Uint8Array(xhr.responseText)) : cb(errInfo); + xhr.readyState === 4 && xhr.status === 200 ? cb(null, new Uint8Array(xhr.response)) : cb(errInfo); }; } xhr.send(null); @@ -102,7 +103,7 @@ cc.loader.loadBinarySync = function (url) { return null; } - arrayInfo = this._str2Uint8Array(req.responseText); + arrayInfo = self._str2Uint8Array(req.responseText); } return arrayInfo; }; @@ -151,4 +152,4 @@ if (cc.loader.loadBinary._IEFilter) { return byteMapping[match]; }) + lastChr; }; -} \ No newline at end of file +} diff --git a/cocos2d/effects/CCGrid.js b/cocos2d/effects/CCGrid.js index f6459a2269..361cba84b3 100644 --- a/cocos2d/effects/CCGrid.js +++ b/cocos2d/effects/CCGrid.js @@ -39,7 +39,7 @@ cc.GridBase = cc.Class.extend(/** @lends cc.GridBase# */{ _step: null, _grabber: null, _isTextureFlipped: false, - _shaderProgram: null, + _glProgramState: null, _directorProjection: 0, _dirty: false, @@ -62,7 +62,7 @@ cc.GridBase = cc.Class.extend(/** @lends cc.GridBase# */{ this._step = cc.p(0, 0); this._grabber = null; this._isTextureFlipped = false; - this._shaderProgram = null; + this._glProgramState = null; this._directorProjection = 0; this._dirty = false; @@ -227,7 +227,7 @@ cc.GridBase = cc.Class.extend(/** @lends cc.GridBase# */{ if (!this._grabber) return false; this._grabber.grab(this._texture); - this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURE); + this._glProgramState = cc.GLProgramState.getOrCreateWithGLProgram(cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURE)); this.calculateVertexPoints(); return true; }, @@ -443,9 +443,7 @@ cc.Grid3D = cc.GridBase.extend(/** @lends cc.Grid3D# */{ this._matrix.mat[5] = wt.d; this._matrix.mat[13] = wt.ty; - this._shaderProgram.use(); - //this._shaderProgram.setUniformsForBuiltins(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix); + this._glProgramState.apply(this._matrix); var gl = cc._renderContext, locDirty = this._dirty; @@ -714,9 +712,7 @@ cc.TiledGrid3D = cc.GridBase.extend(/** @lends cc.TiledGrid3D# */{ this._matrix.mat[5] = wt.d; this._matrix.mat[13] = wt.ty; - this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix); - //this._shaderProgram.setUniformsForBuiltins(); + this._glProgramState.apply(this._matrix); // // Attributes diff --git a/cocos2d/motion-streak/CCMotionStreakWebGLRenderCmd.js b/cocos2d/motion-streak/CCMotionStreakWebGLRenderCmd.js index e2d74f574a..a7d793a336 100644 --- a/cocos2d/motion-streak/CCMotionStreakWebGLRenderCmd.js +++ b/cocos2d/motion-streak/CCMotionStreakWebGLRenderCmd.js @@ -49,8 +49,7 @@ cc.MotionStreak.WebGLRenderCmd.prototype.rendering = function (ctx) { this._matrix.mat[5] = wt.d; this._matrix.mat[13] = wt.ty; - this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix); + this._glProgramState.apply(this._matrix); cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst); cc.glBindTexture2D(node.texture); diff --git a/cocos2d/particle/CCParticleBatchNode.js b/cocos2d/particle/CCParticleBatchNode.js index 3952bcdbbb..53c381fc30 100644 --- a/cocos2d/particle/CCParticleBatchNode.js +++ b/cocos2d/particle/CCParticleBatchNode.js @@ -278,9 +278,6 @@ cc.ParticleBatchNode = cc.Node.extend(/** @lends cc.ParticleBatchNode# */{ return; } - if (zOrder === child.zIndex) - return; - // no reordering if only 1 child if (this._children.length > 1) { var getIndexes = this._getCurrentIndex(child, zOrder); diff --git a/cocos2d/particle/CCParticleBatchNodeWebGLRenderCmd.js b/cocos2d/particle/CCParticleBatchNodeWebGLRenderCmd.js index 3dda639728..765e7553ad 100644 --- a/cocos2d/particle/CCParticleBatchNodeWebGLRenderCmd.js +++ b/cocos2d/particle/CCParticleBatchNodeWebGLRenderCmd.js @@ -49,8 +49,7 @@ this._matrix.mat[5] = wt.d; this._matrix.mat[13] = wt.ty; - this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix); + this._glProgramState.apply(this._matrix); cc.glBlendFuncForParticle(_t._blendFunc.src, _t._blendFunc.dst); _t.textureAtlas.drawQuads(); }; diff --git a/cocos2d/particle/CCParticleSystemCanvasRenderCmd.js b/cocos2d/particle/CCParticleSystemCanvasRenderCmd.js index 781baf7004..5f602e99f2 100644 --- a/cocos2d/particle/CCParticleSystemCanvasRenderCmd.js +++ b/cocos2d/particle/CCParticleSystemCanvasRenderCmd.js @@ -195,11 +195,12 @@ }; proto._updateDeltaColor = function (selParticle, dt) { if (!this._node._dontTint) { - selParticle.color.r += selParticle.deltaColor.r * dt; - selParticle.color.g += selParticle.deltaColor.g * dt; - selParticle.color.b += selParticle.deltaColor.b * dt; - selParticle.color.a += selParticle.deltaColor.a * dt; - selParticle.isChangeColor = true; + var deltaColor = selParticle.deltaColor; + selParticle.color.r += deltaColor.r * dt; + selParticle.color.g += deltaColor.g * dt; + selParticle.color.b += deltaColor.b * dt; + selParticle.color.a += deltaColor.a * dt; + selParticle.isChangeColor = deltaColor.r !== 0 || deltaColor.g !== 0 || deltaColor.b !== 0; } }; })(); diff --git a/cocos2d/particle/CCParticleSystemWebGLRenderCmd.js b/cocos2d/particle/CCParticleSystemWebGLRenderCmd.js index 892f8a2d21..54b1236119 100644 --- a/cocos2d/particle/CCParticleSystemWebGLRenderCmd.js +++ b/cocos2d/particle/CCParticleSystemWebGLRenderCmd.js @@ -204,8 +204,7 @@ this._matrix.mat[5] = wt.d; this._matrix.mat[13] = wt.ty; - this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix); //; + this._glProgramState.apply(this._matrix); cc.glBindTexture2D(node._texture); cc.glBlendFuncForParticle(node._blendFunc.src, node._blendFunc.dst); diff --git a/cocos2d/physics/CCPhysicsDebugNodeWebGLRenderCmd.js b/cocos2d/physics/CCPhysicsDebugNodeWebGLRenderCmd.js index 1c2a9fb69a..0b8a18504c 100644 --- a/cocos2d/physics/CCPhysicsDebugNodeWebGLRenderCmd.js +++ b/cocos2d/physics/CCPhysicsDebugNodeWebGLRenderCmd.js @@ -54,8 +54,7 @@ //cc.DrawNode.prototype.draw.call(node); cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst); - this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix); + this._glProgramState.apply(this._matrix); node._render(); node.clear(); diff --git a/cocos2d/progress-timer/CCProgressTimerWebGLRenderCmd.js b/cocos2d/progress-timer/CCProgressTimerWebGLRenderCmd.js index 8ee5a7da1a..8a89913eed 100644 --- a/cocos2d/progress-timer/CCProgressTimerWebGLRenderCmd.js +++ b/cocos2d/progress-timer/CCProgressTimerWebGLRenderCmd.js @@ -35,6 +35,7 @@ this._bl = cc.p(); this._tr = cc.p(); + this._transformUpdating = false; this.initCmd(); }; @@ -55,7 +56,9 @@ this._tr.x = rx * wt.a + ty * wt.c + wt.tx; this._tr.y = rx * wt.b + ty * wt.d + wt.ty; + this._transformUpdating = true; this._updateProgressData(); + this._transformUpdating = false; }; proto.rendering = function (ctx) { @@ -64,7 +67,7 @@ if (this._vertexDataCount === 0 || !node._sprite) return; - this._shaderProgram.use(); + this._glProgramState.apply(); this._shaderProgram._updateProjectionUniform(); var blendFunc = node._sprite._blendFunc; @@ -449,7 +452,7 @@ this._updateColor(); var locVertexData = this._vertexData; - if (!sameIndexCount) { + if (this._transformUpdating || !sameIndexCount) { // First we populate the array with the m_tMidpoint, then all // vertices/texcoords/colors of the 12 'o clock start and edges and the hitpoint this._textureCoordFromAlphaPoint(locVertexData[0].texCoords, locMidPoint.x, locMidPoint.y); diff --git a/cocos2d/shaders/CCGLProgram.js b/cocos2d/shaders/CCGLProgram.js index 30c6176f11..0cf9f4702d 100644 --- a/cocos2d/shaders/CCGLProgram.js +++ b/cocos2d/shaders/CCGLProgram.js @@ -42,28 +42,30 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ _projectionUpdated: -1, // Uniform cache - _updateUniformLocation: function (location) { - if (!location) + _updateUniform: function (name) { + if (!name) return false; - var updated; - var element = this._hashForUniforms[location]; - - if (!element) { - element = [ - arguments[1], - arguments[2], - arguments[3], - arguments[4] - ]; - this._hashForUniforms[location] = element; + var updated = false; + var element = this._hashForUniforms[name]; + var args; + if (Array.isArray(arguments[1])) { + args = arguments[1]; + } else { + args = new Array(arguments.length - 1); + for (var i = 1; i < arguments.length; i += 1) { + args[i - 1] = arguments[i]; + } + } + + if (!element || element.length !== args.length) { + this._hashForUniforms[name] = [].concat(args); updated = true; } else { - updated = false; - var count = arguments.length - 1; - for (var i = 0; i < count; ++i) { - if (arguments[i + 1] !== element[i]) { - element[i] = arguments[i + 1]; + for (var i = 0; i < args.length; i += 1) { + // Array and Typed Array inner values could be changed, so we must update them + if (args[i] !== element[i] || typeof args[i] === 'object') { + element[i] = args[i]; updated = true; } } @@ -169,9 +171,7 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ if (this._fragShader) locGL.attachShader(this._programObj, this._fragShader); - for (var key in this._hashForUniforms) { - delete this._hashForUniforms[key]; - } + if (Object.keys(this._hashForUniforms).length > 0) this._hashForUniforms = {}; cc.checkGLErrorDebug(); return true; @@ -268,18 +268,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * cc.UNIFORM_SAMPLER */ updateUniforms: function () { - this._uniforms[cc.UNIFORM_PMATRIX_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_PMATRIX_S); - this._uniforms[cc.UNIFORM_MVMATRIX_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_MVMATRIX_S); - this._uniforms[cc.UNIFORM_MVPMATRIX_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_MVPMATRIX_S); - this._uniforms[cc.UNIFORM_TIME_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_TIME_S); - this._uniforms[cc.UNIFORM_SINTIME_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_SINTIME_S); - this._uniforms[cc.UNIFORM_COSTIME_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_COSTIME_S); - + this._addUniformLocation(cc.UNIFORM_PMATRIX_S); + this._addUniformLocation(cc.UNIFORM_MVMATRIX_S); + this._addUniformLocation(cc.UNIFORM_MVPMATRIX_S); + this._addUniformLocation(cc.UNIFORM_TIME_S); + this._addUniformLocation(cc.UNIFORM_SINTIME_S); + this._addUniformLocation(cc.UNIFORM_COSTIME_S); + this._addUniformLocation(cc.UNIFORM_RANDOM01_S); + this._addUniformLocation(cc.UNIFORM_SAMPLER_S); this._usesTime = (this._uniforms[cc.UNIFORM_TIME_S] != null || this._uniforms[cc.UNIFORM_SINTIME_S] != null || this._uniforms[cc.UNIFORM_COSTIME_S] != null); - this._uniforms[cc.UNIFORM_RANDOM01_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_RANDOM01_S); - this._uniforms[cc.UNIFORM_SAMPLER_S] = this._glContext.getUniformLocation(this._programObj, cc.UNIFORM_SAMPLER_S); - this.use(); // Since sample most probably won't change, set it to 0 now. this.setUniformLocationWith1i(this._uniforms[cc.UNIFORM_SAMPLER_S], 0); @@ -287,7 +285,9 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ _addUniformLocation: function (name) { var location = this._glContext.getUniformLocation(this._programObj, name); + if (location) location._name = name; this._uniforms[name] = location; + return location; }, /** @@ -301,7 +301,7 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ if (!this._programObj) throw new Error("cc.GLProgram.getUniformLocationForName(): Invalid operation. Cannot get uniform location when program is not initialized"); - var location = this._uniforms[name] || this._glContext.getUniformLocation(this._programObj, name); + var location = this._uniforms[name] || this._addUniformLocation(name); return location; }, @@ -327,16 +327,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Number} i1 */ setUniformLocationWith1i: function (location, i1) { - var gl = this._glContext; - if (typeof location === 'string') { - var updated = this._updateUniformLocation(location, i1); - if (updated) { - var locObj = this.getUniformLocationForName(location); - gl.uniform1i(locObj, i1); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, i1)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform1i(location, i1); } - } - else { - gl.uniform1i(location, i1); + } else { + this._glContext.uniform1i(location, i1); } }, @@ -347,16 +346,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Number} i2 */ setUniformLocationWith2i: function (location, i1, i2) { - var gl = this._glContext; - if (typeof location === 'string') { - var updated = this._updateUniformLocation(location, i1, i2); - if (updated) { - var locObj = this.getUniformLocationForName(location); - gl.uniform2i(locObj, i1, i2); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, i1, i2)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform2i(location, i1, i2); } - } - else { - gl.uniform2i(location, i1, i2); + } else { + this._glContext.uniform2i(location, i1, i2); } }, @@ -368,16 +366,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Number} i3 */ setUniformLocationWith3i: function (location, i1, i2, i3) { - var gl = this._glContext; - if (typeof location === 'string') { - var updated = this._updateUniformLocation(location, i1, i2, i3); - if (updated) { - var locObj = this.getUniformLocationForName(location); - gl.uniform3i(locObj, i1, i2, i3); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, i1, i2, i3)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform3i(location, i1, i2, i3); } - } - else { - gl.uniform3i(location, i1, i2, i3); + } else { + this._glContext.uniform3i(location, i1, i2, i3); } }, @@ -390,16 +387,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Number} i4 */ setUniformLocationWith4i: function (location, i1, i2, i3, i4) { - var gl = this._glContext; - if (typeof location === 'string') { - var updated = this._updateUniformLocation(location, i1, i2, i3, i4); - if (updated) { - var locObj = this.getUniformLocationForName(location); - gl.uniform4i(locObj, i1, i2, i3, i4); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, i1, i2, i3, i4)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform4i(location, i1, i2, i3, i4); } - } - else { - gl.uniform4i(location, i1, i2, i3, i4); + } else { + this._glContext.uniform4i(location, i1, i2, i3, i4); } }, @@ -410,8 +406,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Number} numberOfArrays */ setUniformLocationWith2iv: function (location, intArray) { - var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location; - this._glContext.uniform2iv(locObj, intArray); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, intArray)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform2iv(location, intArray); + } + } else { + this._glContext.uniform2iv(location, intArray); + } }, /** @@ -420,8 +424,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Int32Array} intArray */ setUniformLocationWith3iv: function (location, intArray) { - var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location; - this._glContext.uniform3iv(locObj, intArray); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, intArray)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform3iv(location, intArray); + } + } else { + this._glContext.uniform3iv(location, intArray); + } }, /** @@ -430,8 +442,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Int32Array} intArray */ setUniformLocationWith4iv: function (location, intArray) { - var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location; - this._glContext.uniform4iv(locObj, intArray); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, intArray)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform4iv(location, intArray); + } + } else { + this._glContext.uniform4iv(location, intArray); + } }, /** @@ -449,16 +469,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Number} f1 */ setUniformLocationWith1f: function (location, f1) { - var gl = this._glContext; - if (typeof location === 'string') { - var updated = this._updateUniformLocation(location, f1); - if (updated) { - var locObj = this.getUniformLocationForName(location); - gl.uniform1f(locObj, f1); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, f1)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform1f(location, f1); } - } - else { - gl.uniform1f(location, f1); + } else { + this._glContext.uniform1f(location, f1); } }, @@ -469,16 +488,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Number} f2 */ setUniformLocationWith2f: function (location, f1, f2) { - var gl = this._glContext; - if (typeof location === 'string') { - var updated = this._updateUniformLocation(location, f1, f2); - if (updated) { - var locObj = this.getUniformLocationForName(location); - gl.uniform2f(locObj, f1, f2); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, f1, f2)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform2f(location, f1, f2); } - } - else { - gl.uniform2f(location, f1, f2); + } else { + this._glContext.uniform2f(location, f1, f2); } }, @@ -490,16 +508,15 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Number} f3 */ setUniformLocationWith3f: function (location, f1, f2, f3) { - var gl = this._glContext; - if (typeof location === 'string') { - var updated = this._updateUniformLocation(location, f1, f2, f3); - if (updated) { - var locObj = this.getUniformLocationForName(location); - gl.uniform3f(locObj, f1, f2, f3); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, f1, f2, f3)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform3f(location, f1, f2, f3); } - } - else { - gl.uniform3f(location, f1, f2, f3); + } else { + this._glContext.uniform3f(location, f1, f2, f3); } }, @@ -512,16 +529,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Number} f4 */ setUniformLocationWith4f: function (location, f1, f2, f3, f4) { - var gl = this._glContext; - if (typeof location === 'string') { - var updated = this._updateUniformLocation(location, f1, f2, f3, f4); - if (updated) { - var locObj = this.getUniformLocationForName(location); - gl.uniform4f(locObj, f1, f2, f3, f4); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, f1, f2, f3, f4)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform4f(location, f1, f2, f3, f4); } - } - else { - gl.uniform4f(location, f1, f2, f3, f4); + } else { + this._glContext.uniform4f(location, f1, f2, f3, f4); + cc.log('uniform4f', f1, f2, f3, f4); } }, @@ -531,8 +548,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Float32Array} floatArray */ setUniformLocationWith2fv: function (location, floatArray) { - var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location; - this._glContext.uniform2fv(locObj, floatArray); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, floatArray)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform2fv(location, floatArray); + } + } else { + this._glContext.uniform2fv(location, floatArray); + } }, /** @@ -541,8 +566,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Float32Array} floatArray */ setUniformLocationWith3fv: function (location, floatArray) { - var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location; - this._glContext.uniform3fv(locObj, floatArray); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, floatArray)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform3fv(location, floatArray); + } + } else { + this._glContext.uniform3fv(location, floatArray); + } }, /** @@ -551,17 +584,53 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Float32Array} floatArray */ setUniformLocationWith4fv: function (location, floatArray) { - var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location; - this._glContext.uniform4fv(locObj, floatArray); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, floatArray)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniform4fv(location, floatArray); + } + } else { + this._glContext.uniform4fv(location, floatArray); + cc.log('uniform4fv', floatArray); + } + }, + + /** + * calls glUniformMatrix2fv + * @param {WebGLUniformLocation|String} location + * @param {Float32Array} matrixArray + */ + setUniformLocationWithMatrix2fv: function (location, matrixArray) { + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, matrixArray)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniformMatrix2fv(location, false, matrixArray); + } + } else { + this._glContext.uniformMatrix2fv(location, false, matrixArray); + } }, + /** * calls glUniformMatrix3fv * @param {WebGLUniformLocation|String} location * @param {Float32Array} matrixArray */ setUniformLocationWithMatrix3fv: function (location, matrixArray) { - var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location; - this._glContext.uniformMatrix3fv(locObj, false, matrixArray); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, matrixArray)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniformMatrix3fv(location, false, matrixArray); + } + } else { + this._glContext.uniformMatrix3fv(location, false, matrixArray); + } }, /** @@ -570,8 +639,16 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * @param {Float32Array} matrixArray */ setUniformLocationWithMatrix4fv: function (location, matrixArray) { - var locObj = typeof location === 'string' ? this.getUniformLocationForName(location) : location; - this._glContext.uniformMatrix4fv(locObj, false, matrixArray); + var isString = typeof location === 'string'; + var name = isString ? location : location && location._name; + if (name) { + if (this._updateUniform(name, matrixArray)) { + if (isString) location = this.getUniformLocationForName(name); + this._glContext.uniformMatrix4fv(location, false, matrixArray); + } + } else { + this._glContext.uniformMatrix4fv(location, false, matrixArray); + } }, setUniformLocationF32: function () { @@ -664,25 +741,25 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ * will update the MVP matrix on the MVP uniform if it is different than the previous call for this same shader program. */ setUniformForModelViewProjectionMatrix: function () { - this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_MVPMATRIX_S], false, + this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_MVPMATRIX_S], cc.getMat4MultiplyValue(cc.projection_matrix_stack.top, cc.modelview_matrix_stack.top)); }, setUniformForModelViewProjectionMatrixWithMat4: function (swapMat4) { cc.kmMat4Multiply(swapMat4, cc.projection_matrix_stack.top, cc.modelview_matrix_stack.top); - this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_MVPMATRIX_S], false, swapMat4.mat); + this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_MVPMATRIX_S], swapMat4.mat); }, setUniformForModelViewAndProjectionMatrixWithMat4: function () { - this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_MVMATRIX_S], false, cc.modelview_matrix_stack.top.mat); - this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_PMATRIX_S], false, cc.projection_matrix_stack.top.mat); + this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_MVMATRIX_S], cc.modelview_matrix_stack.top.mat); + this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_PMATRIX_S], cc.projection_matrix_stack.top.mat); }, _setUniformForMVPMatrixWithMat4: function (modelViewMatrix) { if (!modelViewMatrix) throw new Error("modelView matrix is undefined."); - this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_MVMATRIX_S], false, modelViewMatrix.mat); - this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_PMATRIX_S], false, cc.projection_matrix_stack.top.mat); + this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_MVMATRIX_S], modelViewMatrix.mat); + this.setUniformLocationWithMatrix4fv(this._uniforms[cc.UNIFORM_PMATRIX_S], cc.projection_matrix_stack.top.mat); }, _updateProjectionUniform: function () { @@ -748,7 +825,7 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ reset: function () { this._vertShader = null; this._fragShader = null; - this._uniforms.length = 0; + if (Object.keys(this._uniforms).length > 0) this._uniforms = {}; // it is already deallocated by android //ccGLDeleteProgram(m_uProgram); @@ -756,10 +833,7 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ this._programObj = null; // Purge uniform hash - for (var key in this._hashForUniforms) { - this._hashForUniforms[key].length = 0; - delete this._hashForUniforms[key]; - } + if (Object.keys(this._hashForUniforms).length > 0) this._hashForUniforms = {}; }, /** diff --git a/cocos2d/shaders/CCGLProgramState.js b/cocos2d/shaders/CCGLProgramState.js new file mode 100644 index 0000000000..c5bc2fd428 --- /dev/null +++ b/cocos2d/shaders/CCGLProgramState.js @@ -0,0 +1,303 @@ +/**************************************************************************** + Copyright (c) 2008-2010 Ricardo Quesada + Copyright (c) 2011-2012 cocos2d-x.org + Copyright (c) 2013-2014 Chukong Technologies Inc. + + http://www.cocos2d-x.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ + +var types = + { + GL_FLOAT: 0, + GL_INT: 1, + GL_FLOAT_VEC2: 2, + GL_FLOAT_VEC3: 3, + GL_FLOAT_VEC4: 4, + GL_FLOAT_MAT4: 5, + GL_CALLBACK: 6, + GL_TEXTURE: 7 + }; + + + +cc.UniformValue = function (uniform, glprogram) { + this._uniform = uniform; + this._glprogram = glprogram; + + this._value = null; + this._type = -1; +}; + +cc.UniformValue.prototype = { + setFloat: function setFloat(value) { + this._value = value; + this._type = types.GL_FLOAT; + }, + + setInt: function setInt(value) { + this._value = value; + this._type = types.GL_INT; + }, + + setVec2: function setVec2(v1, v2) { + this._value = [v1, v2]; + this._type = types.GL_FLOAT_VEC2; + }, + + setVec2v: function setVec2v(value) { + this._value = value.slice(0); + this._type = types.GL_FLOAT_VEC2; + }, + + setVec3: function setVec3(v1, v2, v3) { + this._value = [v1, v2, v3]; + this._type = types.GL_FLOAT_VEC3; + }, + + setVec3v: function setVec3v(value) { + this._value = value.slice(0); + this._type = types.GL_FLOAT_VEC3; + }, + + setVec4: function setVec4(v1, v2, v3, v4) { + this._value = [v1, v2, v3, v4]; + this._type = types.GL_FLOAT_VEC4; + }, + + setVec4v: function setVec4v(value) { + this._value = value.slice(0); + this._type = types.GL_FLOAT_VEC4; + }, + + setMat4: function setMat4(value) { + this._value = value.slice(0); + this._type = types.GL_FLOAT_MAT4; + }, + + setCallback: function setCallback(fn) { + this._value = fn; + this._type = types.GL_CALLBACK; + }, + + setTexture: function setTexture(textureId, textureUnit) { + this._value = textureUnit; + this._textureId = textureId; + this._type = types.GL_TEXTURE; + }, + + apply: function apply() { + switch (this._type) { + case types.GL_INT: + this._glprogram.setUniformLocationWith1i(this._uniform._location, this._value); + break; + case types.GL_FLOAT: + this._glprogram.setUniformLocationWith1f(this._uniform._location, this._value); + break; + case types.GL_FLOAT_VEC2: + this._glprogram.setUniformLocationWith2fv(this._uniform._location, this._value); + break; + case types.GL_FLOAT_VEC3: + this._glprogram.setUniformLocationWith3fv(this._uniform._location, this._value); + break; + case types.GL_FLOAT_VEC4: + this._glprogram.setUniformLocationWith4fv(this._uniform._location, this._value); + break; + case types.GL_FLOAT_MAT4: + this._glprogram.setUniformLocationWithMatrix4fv(this._uniform._location, this._value); + break; + case types.GL_CALLBACK: + this._value(this._glprogram, this._uniform); + break; + case types.GL_TEXTURE: + this._glprogram.setUniformLocationWith1i(this._uniform._location, this._value); + cc.glBindTexture2DN(this._value, this._textureId); + break; + default: + ; + } + }, +}; + +cc.GLProgramState = function (glprogram) { + this._glprogram = glprogram; + this._uniforms = {}; + this._boundTextureUnits = {}; + this._textureUnitIndex = 1; // Start at 1, as CC_Texture0 is bound to 0 + + var activeUniforms = glprogram._glContext.getProgramParameter(glprogram._programObj, + glprogram._glContext.ACTIVE_UNIFORMS); + + for (var i = 0; i < activeUniforms; i += 1) { + var uniform = glprogram._glContext.getActiveUniform(glprogram._programObj, i); + if (uniform.name.indexOf("CC_") !== 0) { + uniform._location = glprogram._glContext.getUniformLocation(glprogram._programObj, uniform.name); + uniform._location._name = uniform.name; + var uniformValue = new cc.UniformValue(uniform, glprogram); + this._uniforms[uniform.name] = uniformValue; + } + } +}; + +cc.GLProgramState.prototype = { + apply: function apply(modelView) { + this._glprogram.use(); + if (modelView) { + this._glprogram._setUniformForMVPMatrixWithMat4(modelView); + } + + for (var name in this._uniforms) { + this._uniforms[name].apply(); + }; + }, + + setGLProgram: function setGLProgram(glprogram) { + this._glprogram = glprogram; + }, + + getGLProgram: function getGLProgram() { + return this._glprogram; + }, + + getUniformCount: function getUniformCount() { + return this._uniforms.length; + }, + + getUniformValue: function getUniformValue(uniform) { + return this._uniforms[uniform]; + }, + + setUniformInt: function setUniformInt(uniform, value) { + var v = this.getUniformValue(uniform); + if (v) { + v.setInt(value); + } else { + cc.log("cocos2d: warning: Uniform not found: " + uniform); + } + }, + + setUniformFloat: function setUniformFloat(uniform, value) { + var v = this.getUniformValue(uniform); + if (v) { + v.setFloat(value); + } else { + cc.log("cocos2d: warning: Uniform not found: " + uniform); + } + }, + + setUniformVec2: function setUniformVec2(uniform, v1, v2) { + var v = this.getUniformValue(uniform); + if (v) { + v.setVec2(v1, v2); + } else { + cc.log("cocos2d: warning: Uniform not found: " + uniform); + } + }, + + setUniformVec2v: function setUniformVec2v(uniform, value) { + var v = this.getUniformValue(uniform); + if (v) { + v.setVec2v(value); + } else { + cc.log("cocos2d: warning: Uniform not found: " + uniform); + } + }, + + setUniformVec3: function setUniformVec3(uniform, v1, v2, v3) { + var v = this.getUniformValue(uniform); + if (v) { + v.setVec3(v1, v2, v3); + } else { + cc.log("cocos2d: warning: Uniform not found: " + uniform); + } + }, + + setUniformVec3v: function setUniformVec3v(uniform, value) { + var v = this.getUniformValue(uniform); + if (v) { + v.setVec3v(value); + } else { + cc.log("cocos2d: warning: Uniform not found: " + uniform); + } + }, + + setUniformVec4: function setUniformVec4(uniform, v1, v2, v3, v4) { + var v = this.getUniformValue(uniform); + if (v) { + v.setVec4(v1, v2, v3, v4); + } else { + cc.log("cocos2d: warning: Uniform not found: " + uniform); + } + }, + + setUniformVec4v: function setUniformVec4v(uniform, value) { + var v = this.getUniformValue(uniform); + if (v) { + v.setVec4v(value); + } else { + cc.log("cocos2d: warning: Uniform not found: " + uniform); + } + }, + + + setUniformMat4: function setUniformMat4(uniform, value) { + var v = this.getUniformValue(uniform); + if (v) { + v.setMat4(value); + } else { + cc.log("cocos2d: warning: Uniform not found: " + uniform); + } + + }, + + setUniformCallback: function setUniformCallback(uniform, callback) { + var v = this.getUniformValue(uniform); + if (v) { + v.setCallback(callback); + } else { + cc.log("cocos2d: warning: Uniform not found: " + uniform); + } + + }, + + setUniformTexture: function setUniformTexture(uniform, texture) { + var uniformValue = this.getUniformValue(uniform); + if (uniformValue) { + var textureUnit = this._boundTextureUnits[uniform]; + if (textureUnit) { + uniformValue.setTexture(texture, textureUnit); + } else { + uniformValue.setTexture(texture, this._textureUnitIndex); + this._boundTextureUnits[uniform] = this._textureUnitIndex++; + } + } + } +}; + +cc.GLProgramState._cache = {}; +cc.GLProgramState.getOrCreateWithGLProgram = function (glprogram) { + var programState = cc.GLProgramState._cache[glprogram.__instanceId]; + if (!programState) { + programState = new cc.GLProgramState(glprogram); + cc.GLProgramState._cache[glprogram.__instanceId] = programState; + } + + return programState; +}; diff --git a/cocos2d/shape-nodes/CCDrawNodeWebGLRenderCmd.js b/cocos2d/shape-nodes/CCDrawNodeWebGLRenderCmd.js index ef9d443c98..cd7ea5125c 100644 --- a/cocos2d/shape-nodes/CCDrawNodeWebGLRenderCmd.js +++ b/cocos2d/shape-nodes/CCDrawNodeWebGLRenderCmd.js @@ -45,8 +45,7 @@ this._matrix.mat[13] = wt.ty; cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst); - this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix); + this._glProgramState.apply(this._matrix); node._render(); } }; diff --git a/extensions/ccui/uiwidgets/UIButton.js b/extensions/ccui/uiwidgets/UIButton.js index 4feff73686..4741e2e767 100644 --- a/extensions/ccui/uiwidgets/UIButton.js +++ b/extensions/ccui/uiwidgets/UIButton.js @@ -33,7 +33,7 @@ * @property {String} titleFont - The content string font of the button title * @property {Number} titleFontSize - The content string font size of the button title * @property {String} titleFontName - The content string font name of the button title - * @property {cc.Color} titleFontColor - The content string font color of the button title + * @property {cc.Color} titleColor - The content string font color of the button title * @property {Boolean} pressedActionEnabled - Indicate whether button has zoom effect when clicked */ ccui.Button = ccui.Widget.extend(/** @lends ccui.Button# */{ diff --git a/extensions/cocostudio/armature/CCArmatureWebGLRenderCmd.js b/extensions/cocostudio/armature/CCArmatureWebGLRenderCmd.js index bf48084815..6f24c7b677 100644 --- a/extensions/cocostudio/armature/CCArmatureWebGLRenderCmd.js +++ b/extensions/cocostudio/armature/CCArmatureWebGLRenderCmd.js @@ -118,7 +118,7 @@ }; proto.setShaderProgram = function (shaderProgram) { - this._shaderProgram = shaderProgram; + this._glProgramState = cc.GLProgramState.getOrCreateWithGLProgram(shaderProgram); }; proto._updateColorAndOpacity = function (skinRenderCmd, bone) { diff --git a/extensions/editbox/CCEditBox.js b/extensions/editbox/CCEditBox.js index 5fa8044506..3a535438f2 100644 --- a/extensions/editbox/CCEditBox.js +++ b/extensions/editbox/CCEditBox.js @@ -154,14 +154,14 @@ cc.EditBoxDelegate = cc.Class.extend({ * This method is called when an edit box gains focus after keyboard is shown. * @param {cc.EditBox} sender */ - editBoxEditingDidBegan: function (sender) { + editBoxEditingDidBegin: function (sender) { }, /** * This method is called when an edit box loses focus after keyboard is hidden. * @param {cc.EditBox} sender */ - editBoxEditingDidEnded: function (sender) { + editBoxEditingDidEnd: function (sender) { }, /** @@ -176,7 +176,7 @@ cc.EditBoxDelegate = cc.Class.extend({ * This method is called when the return button was pressed. * @param {cc.EditBox} sender */ - editBoxEditingReturn: function (sender) { + editBoxReturn: function (sender) { } }); @@ -219,6 +219,8 @@ cc.EditBox = cc.Node.extend({ _placeholderFontSize: 14, _placeholderColor: null, _className: 'EditBox', + _touchListener: null, + _touchEnabled: true, /** * constructor of cc.EditBox @@ -238,16 +240,29 @@ cc.EditBox = cc.Node.extend({ this.createDomElementIfNeeded(); this.initWithSizeAndBackgroundSprite(size, normal9SpriteBg); - cc.eventManager.addListener({ + this._touchListener = cc.EventListener.create({ event: cc.EventListener.TOUCH_ONE_BY_ONE, swallowTouches: true, onTouchBegan: this._onTouchBegan.bind(this), onTouchEnded: this._onTouchEnded.bind(this) - }, this); + }); + cc.eventManager.addListener(this._touchListener, this); this.setInputFlag(this._editBoxInputFlag); }, + setTouchEnabled: function (enable) { + if (this._touchEnabled === enable) { + return; + } + this._touchEnabled = enable; + if (this._touchEnabled) { + cc.eventManager.addListener(this._touchListener, this); + } else { + cc.eventManager.removeListener(this._touchListener); + } + }, + _createRenderCmd: function () { if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) { return new cc.EditBox.CanvasRenderCmd(this); @@ -317,7 +332,21 @@ cc.EditBox = cc.Node.extend({ this._renderCmd._removeDomFromGameContainer(); }, + _isAncestorsVisible: function (node) { + if (null == node) + return true; + + var parent = node.getParent(); + + if (parent && !parent.isVisible()) + return false; + return this._isAncestorsVisible(parent); + }, + _onTouchBegan: function (touch) { + if (!this.isVisible() || !this._isAncestorsVisible(this)) { + return; + } var touchPoint = touch.getLocation(); var bb = cc.rect(0, 0, this._contentSize.width, this._contentSize.height); var hitted = cc.rectContainsPoint(bb, this.convertToNodeSpace(touchPoint)); @@ -331,6 +360,9 @@ cc.EditBox = cc.Node.extend({ }, _onTouchEnded: function () { + if (!this.isVisible() || !this._isAncestorsVisible(this)) { + return; + } this._renderCmd._beginEditing(); }, @@ -822,6 +854,7 @@ cc.EditBox.create = function (size, normal9SpriteBg, press9SpriteBg, disabled9Sp var thisPointer = this; var tmpEdTxt = this._edTxt = document.createElement('input'); tmpEdTxt.type = 'text'; + tmpEdTxt.style.fontFamily = this._edFontName; tmpEdTxt.style.fontSize = this._edFontSize + 'px'; tmpEdTxt.style.color = '#000000'; tmpEdTxt.style.border = 0; @@ -871,8 +904,8 @@ cc.EditBox.create = function (size, normal9SpriteBg, press9SpriteBg, disabled9Sp thisPointer._updateDomTextCases(); thisPointer._endEditing(); - if (editBox._delegate && editBox._delegate.editBoxEditingReturn) { - editBox._delegate.editBoxEditingReturn(editBox); + if (editBox._delegate && editBox._delegate.editBoxReturn) { + editBox._delegate.editBoxReturn(editBox); } cc._canvas.focus(); } @@ -888,8 +921,8 @@ cc.EditBox.create = function (size, normal9SpriteBg, press9SpriteBg, disabled9Sp thisPointer._onFocusOnMobile(editBox); } - if (editBox._delegate && editBox._delegate.editBoxEditingDidBegan) { - editBox._delegate.editBoxEditingDidBegan(editBox); + if (editBox._delegate && editBox._delegate.editBoxEditingDidBegin) { + editBox._delegate.editBoxEditingDidBegin(editBox); } }); tmpEdTxt.addEventListener('blur', function () { @@ -897,8 +930,8 @@ cc.EditBox.create = function (size, normal9SpriteBg, press9SpriteBg, disabled9Sp editBox._text = this.value; thisPointer._updateDomTextCases(); - if (editBox._delegate && editBox._delegate.editBoxEditingDidEnded) { - editBox._delegate.editBoxEditingDidEnded(editBox); + if (editBox._delegate && editBox._delegate.editBoxEditingDidEnd) { + editBox._delegate.editBoxEditingDidEnd(editBox); } if (this.value === '') { @@ -917,6 +950,7 @@ cc.EditBox.create = function (size, normal9SpriteBg, press9SpriteBg, disabled9Sp var thisPointer = this; var tmpEdTxt = this._edTxt = document.createElement('textarea'); tmpEdTxt.type = 'text'; + tmpEdTxt.style.fontFamily = this._edFontName; tmpEdTxt.style.fontSize = this._edFontSize + 'px'; tmpEdTxt.style.color = '#000000'; tmpEdTxt.style.border = 0; @@ -962,8 +996,8 @@ cc.EditBox.create = function (size, normal9SpriteBg, press9SpriteBg, disabled9Sp thisPointer._onFocusOnMobile(editBox); } - if (editBox._delegate && editBox._delegate.editBoxEditingDidBegan) { - editBox._delegate.editBoxEditingDidBegan(editBox); + if (editBox._delegate && editBox._delegate.editBoxEditingDidBegin) { + editBox._delegate.editBoxEditingDidBegin(editBox); } }); @@ -973,8 +1007,8 @@ cc.EditBox.create = function (size, normal9SpriteBg, press9SpriteBg, disabled9Sp if (e.keyCode === cc.KEY.enter) { e.stopPropagation(); - if (editBox._delegate && editBox._delegate.editBoxEditingReturn) { - editBox._delegate.editBoxEditingReturn(editBox); + if (editBox._delegate && editBox._delegate.editBoxReturn) { + editBox._delegate.editBoxReturn(editBox); } } }); @@ -983,8 +1017,8 @@ cc.EditBox.create = function (size, normal9SpriteBg, press9SpriteBg, disabled9Sp editBox._text = this.value; thisPointer._updateDomTextCases(); - if (editBox._delegate && editBox._delegate.editBoxEditingDidEnded) { - editBox._delegate.editBoxEditingDidEnded(editBox); + if (editBox._delegate && editBox._delegate.editBoxEditingDidEnd) { + editBox._delegate.editBoxEditingDidEnd(editBox); } if (this.value === '') { diff --git a/extensions/spine/CCSkeleton.js b/extensions/spine/CCSkeleton.js index d7f35ebf71..97a99f4edb 100644 --- a/extensions/spine/CCSkeleton.js +++ b/extensions/spine/CCSkeleton.js @@ -31,33 +31,7 @@ */ var sp = sp || {}; -/** - * The vertex index of spine. - * @constant - * @type {{X1: number, Y1: number, X2: number, Y2: number, X3: number, Y3: number, X4: number, Y4: number}} - */ -sp.VERTEX_INDEX = { - X1: 0, - Y1: 1, - X2: 2, - Y2: 3, - X3: 4, - Y3: 5, - X4: 6, - Y4: 7 -}; - -/** - * The attachment type of spine. It contains three type: REGION(0), BOUNDING_BOX(1), MESH(2) and SKINNED_MESH. - * @constant - * @type {{REGION: number, BOUNDING_BOX: number, REGION_SEQUENCE: number, MESH: number}} - */ -sp.ATTACHMENT_TYPE = { - REGION: 0, - BOUNDING_BOX: 1, - MESH: 2, - SKINNED_MESH:3 -}; +var spine = sp.spine; /** *
@@ -78,7 +52,6 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
_premultipliedAlpha: false,
_ownsSkeletonData: null,
_atlas: null,
- _blendFunc: null,
/**
* The constructor of sp.Skeleton. override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
@@ -105,10 +78,18 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
init: function () {
cc.Node.prototype.init.call(this);
this._premultipliedAlpha = (cc._renderType === cc.game.RENDER_TYPE_WEBGL && cc.OPTIMIZE_BLEND_FUNC_FOR_PREMULTIPLIED_ALPHA);
- this._blendFunc = {src: cc.BLEND_SRC, dst: cc.BLEND_DST};
+ },
+
+ onEnter: function () {
+ cc.Node.prototype.onEnter.call(this);
this.scheduleUpdate();
},
+ onExit: function () {
+ this.unscheduleUpdate();
+ cc.Node.prototype.onExit.call(this);
+ },
+
/**
* Sets whether open debug slots.
* @param {boolean} enable true to open, false to close.
@@ -171,7 +152,7 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
/**
* Initializes sp.Skeleton with Data.
- * @param {spine.SkeletonData|String} skeletonDataFile
+ * @param {sp.spine.SkeletonData|String} skeletonDataFile
* @param {String|spine.Atlas|spine.SkeletonData} atlasFile atlas filename or atlas data or owns SkeletonData
* @param {Number} [scale] scale can be specified on the JSON or binary loader which will scale the bone positions, image sizes, and animation translations.
*/
@@ -211,19 +192,20 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
*/
getBoundingBox: function () {
var minX = cc.FLT_MAX, minY = cc.FLT_MAX, maxX = cc.FLT_MIN, maxY = cc.FLT_MIN;
- var scaleX = this.getScaleX(), scaleY = this.getScaleY(), vertices = [],
+ var scaleX = this.getScaleX(), scaleY = this.getScaleY(), vertices,
slots = this._skeleton.slots, VERTEX = spine.RegionAttachment;
for (var i = 0, slotCount = slots.length; i < slotCount; ++i) {
var slot = slots[i];
var attachment = slot.attachment;
- if (!attachment || ! (attachment instanceof spine.RegionAttachment))
+ if (!attachment || !(attachment instanceof spine.RegionAttachment))
continue;
- vertices = attachment.updateWorldVertices(slot, false);
- minX = Math.min(minX, vertices[VERTEX.X1] * scaleX, vertices[VERTEX.X4] * scaleX, vertices[VERTEX.X2] * scaleX, vertices[VERTEX.X3] * scaleX);
- minY = Math.min(minY, vertices[VERTEX.Y1] * scaleY, vertices[VERTEX.Y4] * scaleY, vertices[VERTEX.Y2] * scaleY, vertices[VERTEX.Y3] * scaleY);
- maxX = Math.max(maxX, vertices[VERTEX.X1] * scaleX, vertices[VERTEX.X4] * scaleX, vertices[VERTEX.X2] * scaleX, vertices[VERTEX.X3] * scaleX);
- maxY = Math.max(maxY, vertices[VERTEX.Y1] * scaleY, vertices[VERTEX.Y4] * scaleY, vertices[VERTEX.Y2] * scaleY, vertices[VERTEX.Y3] * scaleY);
+ vertices = spine.Utils.setArraySize(new Array(), 8, 0);
+ attachment.computeWorldVertices(slot.bone, vertices, 0, 2);
+ minX = Math.min(minX, vertices[VERTEX.OX1] * scaleX, vertices[VERTEX.OX4] * scaleX, vertices[VERTEX.OX2] * scaleX, vertices[VERTEX.OX3] * scaleX);
+ minY = Math.min(minY, vertices[VERTEX.OY1] * scaleY, vertices[VERTEX.OY4] * scaleY, vertices[VERTEX.OY2] * scaleY, vertices[VERTEX.OY3] * scaleY);
+ maxX = Math.max(maxX, vertices[VERTEX.OX1] * scaleX, vertices[VERTEX.OX4] * scaleX, vertices[VERTEX.OX2] * scaleX, vertices[VERTEX.OX3] * scaleX);
+ maxY = Math.max(maxY, vertices[VERTEX.OY1] * scaleY, vertices[VERTEX.OY4] * scaleY, vertices[VERTEX.OY2] * scaleY, vertices[VERTEX.OY3] * scaleY);
}
var position = this.getPosition();
return cc.rect(position.x + minX, position.y + minY, maxX - minX, maxY - minY);
@@ -260,7 +242,7 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
/**
* Finds a bone by name. This does a string comparison for every bone.
* @param {String} boneName
- * @returns {spine.Bone}
+ * @returns {sp.spine.Bone}
*/
findBone: function (boneName) {
return this._skeleton.findBone(boneName);
@@ -269,7 +251,7 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
/**
* Finds a slot by name. This does a string comparison for every slot.
* @param {String} slotName
- * @returns {spine.Slot}
+ * @returns {sp.spine.Slot}
*/
findSlot: function (slotName) {
return this._skeleton.findSlot(slotName);
@@ -278,7 +260,7 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
/**
* Finds a skin by name and makes it the active skin. This does a string comparison for every skin. Note that setting the skin does not change which attachments are visible.
* @param {string} skinName
- * @returns {spine.Skin}
+ * @returns {sp.spine.Skin}
*/
setSkin: function (skinName) {
return this._skeleton.setSkinByName(skinName);
@@ -288,7 +270,7 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
* Returns the attachment for the slot and attachment name. The skeleton looks first in its skin, then in the skeleton data’s default skin.
* @param {String} slotName
* @param {String} attachmentName
- * @returns {spine.RegionAttachment|spine.BoundingBoxAttachment}
+ * @returns {sp.spine.Attachment}
*/
getAttachment: function (slotName, attachmentName) {
return this._skeleton.getAttachmentByName(slotName, attachmentName);
@@ -321,8 +303,8 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
/**
* Sets skeleton data to sp.Skeleton.
- * @param {spine.SkeletonData} skeletonData
- * @param {spine.SkeletonData} ownsSkeletonData
+ * @param {sp.spine.SkeletonData} skeletonData
+ * @param {sp.spine.SkeletonData} ownsSkeletonData
*/
setSkeletonData: function (skeletonData, ownsSkeletonData) {
if(skeletonData.width != null && skeletonData.height != null)
@@ -338,8 +320,8 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
/**
* Return the renderer of attachment.
- * @param {spine.RegionAttachment|spine.BoundingBoxAttachment} regionAttachment
- * @returns {cc.Node}
+ * @param {sp.spine.RegionAttachment|sp.spine.BoundingBoxAttachment} regionAttachment
+ * @returns {sp.spine.TextureAtlasRegion}
*/
getTextureAtlas: function (regionAttachment) {
return regionAttachment.region;
@@ -350,23 +332,23 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
* @returns {cc.BlendFunc}
*/
getBlendFunc: function () {
- return this._blendFunc;
+ var slot = this._skeleton.drawOrder[0];
+ if (slot) {
+ var blend = this._renderCmd._getBlendFunc(slot.data.blendMode, this._premultipliedAlpha);
+ return blend;
+ }
+ else {
+ return {};
+ }
},
/**
- * Sets the blendFunc of sp.Skeleton.
+ * Sets the blendFunc of sp.Skeleton, it won't have any effect for skeleton, skeleton is using slot's data to determine the blend function.
* @param {cc.BlendFunc|Number} src
* @param {Number} [dst]
*/
setBlendFunc: function (src, dst) {
- var locBlendFunc = this._blendFunc;
- if (dst === undefined) {
- locBlendFunc.src = src.src;
- locBlendFunc.dst = src.dst;
- } else {
- locBlendFunc.src = src;
- locBlendFunc.dst = dst;
- }
+ return;
},
/**
@@ -378,6 +360,14 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
}
});
+cc.defineGetterSetter(sp.Skeleton.prototype, "opacityModifyRGB", sp.Skeleton.prototype.isOpacityModifyRGB);
+
+// For renderer webgl to identify skeleton's default texture and blend function
+cc.defineGetterSetter(sp.Skeleton.prototype, "_blendFunc", sp.Skeleton.prototype.getBlendFunc);
+cc.defineGetterSetter(sp.Skeleton.prototype, '_texture', function () {
+ return this._renderCmd._currTexture;
+});
+
/**
* Creates a skeleton object.
* @deprecated since v3.0, please use new sp.Skeleton(skeletonDataFile, atlasFile, scale) instead.
diff --git a/extensions/spine/CCSkeletonAnimation.js b/extensions/spine/CCSkeletonAnimation.js
index 339bd08f15..17f0f25675 100644
--- a/extensions/spine/CCSkeletonAnimation.js
+++ b/extensions/spine/CCSkeletonAnimation.js
@@ -32,8 +32,7 @@ sp._atlasLoader = {
load:function(line){
var texturePath = cc.path.join(cc.path.dirname(this.spAtlasFile), line);
var texture = cc.textureCache.addImage(texturePath);
- var tex = new sp.SkeletonTexture();
- tex._image = { width: texture.getPixelsWide(), height: texture.getPixelsHigh() };
+ var tex = new sp.SkeletonTexture({ width: texture.getPixelsWide(), height: texture.getPixelsHigh() });
tex.setRealTexture(texture);
return tex;
},
@@ -55,7 +54,7 @@ sp.ANIMATION_EVENT_TYPE = {
EVENT: 5
};
-sp.TrackEntryListeners = function(startListener, endListener, completeListener, eventListener, interruptListener, disposeListener){
+sp.TrackEntryListeners = function (startListener, endListener, completeListener, eventListener, interruptListener, disposeListener) {
this.startListener = startListener || null;
this.endListener = endListener || null;
this.completeListener = completeListener || null;
@@ -156,7 +155,7 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
/**
* Sets animation state data to sp.SkeletonAnimation.
- * @param {spine.AnimationStateData} stateData
+ * @param {sp.spine.AnimationStateData} stateData
*/
setAnimationStateData: function (stateData) {
var state = new spine.AnimationState(stateData);
@@ -192,7 +191,7 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
* @param {Number} trackIndex
* @param {String} name
* @param {Boolean} loop
- * @returns {spine.TrackEntry|null}
+ * @returns {sp.spine.TrackEntry|null}
*/
setAnimation: function (trackIndex, name, loop) {
var animation = this._skeleton.data.findAnimation(name);
@@ -209,7 +208,7 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
* @param {String} name
* @param {Boolean} loop
* @param {Number} [delay=0]
- * @returns {spine.TrackEntry|null}
+ * @returns {sp.spine.TrackEntry|null}
*/
addAnimation: function (trackIndex, name, loop, delay) {
delay = delay == null ? 0 : delay;
@@ -221,10 +220,19 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
return this._state.addAnimationWith(trackIndex, animation, loop, delay);
},
+ /**
+ * Find animation with specified name
+ * @param {String} name
+ * @returns {sp.spine.Animation|null}
+ */
+ findAnimation: function (name) {
+ return this._skeleton.data.findAnimation(name);
+ },
+
/**
* Returns track entry by trackIndex.
* @param trackIndex
- * @returns {spine.TrackEntry|null}
+ * @returns {sp.spine.TrackEntry|null}
*/
getCurrent: function (trackIndex) {
return this._state.getCurrent(trackIndex);
@@ -254,6 +262,7 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
update: function (dt) {
this._super(dt);
dt *= this._timeScale;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.contentDirty);
this._state.update(dt);
this._state.apply(this._skeleton);
this._skeleton.updateWorldTransform();
@@ -339,4 +348,4 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
*/
sp.SkeletonAnimation.createWithJsonFile = sp.SkeletonAnimation.create = function (skeletonDataFile, atlasFile/* or atlas*/, scale) {
return new sp.SkeletonAnimation(skeletonDataFile, atlasFile, scale);
-};
\ No newline at end of file
+};
diff --git a/extensions/spine/CCSkeletonCanvasRenderCmd.js b/extensions/spine/CCSkeletonCanvasRenderCmd.js
index 2b20f3f97c..f31924ec19 100644
--- a/extensions/spine/CCSkeletonCanvasRenderCmd.js
+++ b/extensions/spine/CCSkeletonCanvasRenderCmd.js
@@ -23,208 +23,225 @@
****************************************************************************/
(function () {
- sp.Skeleton.CanvasRenderCmd = function (renderableObject) {
- this._rootCtor(renderableObject);
- this._needDraw = true;
- };
-
- var proto = sp.Skeleton.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
- proto.constructor = sp.Skeleton.CanvasRenderCmd;
-
- proto.rendering = function (wrapper, scaleX, scaleY) {
- var node = this._node, i, n, slot, slotNode;
- wrapper = wrapper || cc._renderContext;
-
- var locSkeleton = node._skeleton, drawOrder = locSkeleton.drawOrder;
- for (i = 0, n = drawOrder.length; i < n; i++) {
- slot = drawOrder[i];
- slotNode = slot._slotNode;
- if (slotNode._visible && slotNode._renderCmd && slot.currentSprite) {
- slotNode._renderCmd.transform(this, true);
- slot.currentSprite._renderCmd.rendering(wrapper, scaleX, scaleY);
- slotNode._renderCmd._dirtyFlag = slot.currentSprite._renderCmd._dirtyFlag = 0;
- }
- }
- if (!node._debugSlots && !node._debugBones)
- return;
-
- wrapper.setTransform(this._worldTransform, scaleX, scaleY);
- wrapper.setGlobalAlpha(1);
- var attachment, drawingUtil = cc._drawingUtil;
- if (node._debugSlots) {
- // Slots.
- drawingUtil.setDrawColor(0, 0, 255, 255);
- drawingUtil.setLineWidth(1);
-
- var points = [];
- for (i = 0, n = locSkeleton.slots.length; i < n; i++) {
- slot = locSkeleton.drawOrder[i];
- if (!slot.attachment || !(slot.attachment instanceof spine.RegionAttachment))
- continue;
- attachment = slot.attachment;
- this._updateRegionAttachmentSlot(attachment, slot, points);
- drawingUtil.drawPoly(points, 4, true);
- }
- }
+var spine = sp.spine;
- if (node._debugBones) {
- // Bone lengths.
- var bone;
- drawingUtil.setLineWidth(2);
- drawingUtil.setDrawColor(255, 0, 0, 255);
-
- for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
- bone = locSkeleton.bones[i];
- var x = bone.data.length * bone.a + bone.worldX;
- var y = bone.data.length * bone.c + bone.worldY;
- drawingUtil.drawLine(
- {x: bone.worldX, y: bone.worldY},
- {x: x, y: y});
- }
+sp.Skeleton.CanvasRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = true;
+};
- // Bone origins.
- drawingUtil.setPointSize(4);
- drawingUtil.setDrawColor(0, 0, 255, 255); // Root bone is blue.
+var proto = sp.Skeleton.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+proto.constructor = sp.Skeleton.CanvasRenderCmd;
- for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
- bone = locSkeleton.bones[i];
- drawingUtil.drawPoint({x: bone.worldX, y: bone.worldY});
- if (i === 0)
- drawingUtil.setDrawColor(0, 255, 0, 255);
- }
+proto.rendering = function (wrapper, scaleX, scaleY) {
+ var node = this._node, i, n, slot, slotNode;
+ wrapper = wrapper || cc._renderContext;
+
+ var locSkeleton = node._skeleton, drawOrder = locSkeleton.drawOrder;
+ for (i = 0, n = drawOrder.length; i < n; i++) {
+ slot = drawOrder[i];
+ slotNode = slot._slotNode;
+ if (slotNode._visible && slotNode._renderCmd && slot.currentSprite) {
+ slotNode._renderCmd.transform(this, true);
+ slot.currentSprite._renderCmd.rendering(wrapper, scaleX, scaleY);
+ slotNode._renderCmd._dirtyFlag = slot.currentSprite._renderCmd._dirtyFlag = 0;
}
- };
-
- proto._updateRegionAttachmentSlot = function (attachment, slot, points) {
- if (!points)
- return;
-
- var vertices = attachment.updateWorldVertices(slot, false);
- var VERTEX = spine.RegionAttachment;
- points.length = 0;
- points.push(cc.p(vertices[VERTEX.X1], vertices[VERTEX.Y1]));
- points.push(cc.p(vertices[VERTEX.X4], vertices[VERTEX.Y4]));
- points.push(cc.p(vertices[VERTEX.X3], vertices[VERTEX.Y3]));
- points.push(cc.p(vertices[VERTEX.X2], vertices[VERTEX.Y2]));
- };
-
- proto._createChildFormSkeletonData = function () {
- var node = this._node;
- var locSkeleton = node._skeleton, spriteName, sprite;
- for (var i = 0, n = locSkeleton.slots.length; i < n; i++) {
- var slot = locSkeleton.slots[i], attachment = slot.attachment;
- var slotNode = new cc.Node();
- slot._slotNode = slotNode;
-
- if (attachment instanceof spine.RegionAttachment) {
- spriteName = attachment.region.name;
- sprite = this._createSprite(slot, attachment);
- slot.currentSprite = sprite;
- slot.currentSpriteName = spriteName;
- slotNode.addChild(sprite);
- } else if (attachment instanceof spine.MeshAttachment) {
- //todo for mesh
- }
+ }
+
+ if (!node._debugSlots && !node._debugBones)
+ return;
+
+ wrapper.setTransform(this._worldTransform, scaleX, scaleY);
+ wrapper.setGlobalAlpha(1);
+ var attachment, drawingUtil = cc._drawingUtil;
+ if (node._debugSlots) {
+ // Slots.
+ drawingUtil.setDrawColor(0, 0, 255, 255);
+ drawingUtil.setLineWidth(1);
+
+ var points = [];
+ for (i = 0, n = locSkeleton.slots.length; i < n; i++) {
+ slot = locSkeleton.drawOrder[i];
+ if (!slot.attachment || !(slot.attachment instanceof spine.RegionAttachment))
+ continue;
+ attachment = slot.attachment;
+ this._updateRegionAttachmentSlot(attachment, slot, points);
+ drawingUtil.drawPoly(points, 4, true);
}
- };
-
- var loaded = function (sprite, texture, rendererObject, attachment) {
- var rect = new cc.Rect(rendererObject.x, rendererObject.y, rendererObject.width, rendererObject.height);
- sprite.initWithTexture(texture, rect, rendererObject.rotate, false);
- sprite._rect.width = attachment.width;
- sprite._rect.height = attachment.height;
- sprite.setContentSize(attachment.width, attachment.height);
- sprite.setRotation(-attachment.rotation);
- sprite.setScale(rendererObject.width / rendererObject.originalWidth * attachment.scaleX,
- rendererObject.height / rendererObject.originalHeight * attachment.scaleY);
- };
-
- proto._createSprite = function (slot, attachment) {
- var rendererObject = attachment.region;
- var texture = rendererObject.texture.getRealTexture();
- var sprite = new cc.Sprite();
- if (texture.isLoaded()) {
- loaded(sprite, texture, rendererObject, attachment);
- } else {
- texture.addEventListener('load', function () {
- loaded(sprite, texture, rendererObject, attachment);
- }, this);
+ }
+
+ if (node._debugBones) {
+ // Bone lengths.
+ var bone;
+ drawingUtil.setLineWidth(2);
+ drawingUtil.setDrawColor(255, 0, 0, 255);
+
+ for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
+ bone = locSkeleton.bones[i];
+ var x = bone.data.length * bone.a + bone.worldX;
+ var y = bone.data.length * bone.c + bone.worldY;
+ drawingUtil.drawLine(
+ {x: bone.worldX, y: bone.worldY},
+ {x: x, y: y});
}
- slot.sprites = slot.sprites || {};
- slot.sprites[rendererObject.name] = sprite;
- return sprite;
- };
-
- proto._updateChild = function () {
- var locSkeleton = this._node._skeleton, slots = locSkeleton.slots;
- var color = this._displayedColor, opacity = this._displayedOpacity;
- var i, n, selSprite, ax, ay;
-
- var slot, attachment, slotNode;
- for (i = 0, n = slots.length; i < n; i++) {
- slot = slots[i];
- attachment = slot.attachment;
- slotNode = slot._slotNode;
- if (!attachment) {
- slotNode.setVisible(false);
- continue;
- }
- if (attachment instanceof spine.RegionAttachment){
- if (attachment.region) {
- if (!slot.currentSpriteName || slot.currentSpriteName !== attachment.name) {
- var spriteName = attachment.region.name;
- if (slot.currentSprite !== undefined)
- slot.currentSprite.setVisible(false);
- slot.sprites = slot.sprites || {};
- if (slot.sprites[spriteName] !== undefined)
- slot.sprites[spriteName].setVisible(true);
- else {
- var sprite = this._createSprite(slot, attachment);
- slotNode.addChild(sprite);
- }
- slot.currentSprite = slot.sprites[spriteName];
- slot.currentSpriteName = spriteName;
+
+ // Bone origins.
+ var pointSize = 4;
+ drawingUtil.setDrawColor(0, 0, 255, 255); // Root bone is blue.
+
+ for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
+ bone = locSkeleton.bones[i];
+ drawingUtil.drawPoint({x: bone.worldX, y: bone.worldY}, pointSize);
+ if (i === 0)
+ drawingUtil.setDrawColor(0, 255, 0, 255);
+ }
+ }
+};
+
+proto.updateStatus = function() {
+ this.originUpdateStatus();
+ this._updateCurrentRegions();
+ this._regionFlag = cc.Node.CanvasRenderCmd.RegionStatus.DirtyDouble;
+ this._dirtyFlag &= ~cc.Node._dirtyFlags.contentDirty;
+};
+
+proto.getLocalBB = function() {
+ return this._node.getBoundingBox();
+};
+
+proto._updateRegionAttachmentSlot = function (attachment, slot, points) {
+ if (!points)
+ return;
+
+ var vertices = spine.Utils.setArraySize(new Array(), 8, 0);
+ attachment.computeWorldVertices(slot.bone, vertices, 0, 2);
+ var VERTEX = spine.RegionAttachment;
+ points.length = 0;
+ points.push(cc.p(vertices[VERTEX.OX1], vertices[VERTEX.OY1]));
+ points.push(cc.p(vertices[VERTEX.OX4], vertices[VERTEX.OY4]));
+ points.push(cc.p(vertices[VERTEX.OX3], vertices[VERTEX.OY3]));
+ points.push(cc.p(vertices[VERTEX.OX2], vertices[VERTEX.OY2]));
+};
+
+proto._createChildFormSkeletonData = function () {
+ var node = this._node;
+ var locSkeleton = node._skeleton, spriteName, sprite;
+ for (var i = 0, n = locSkeleton.slots.length; i < n; i++) {
+ var slot = locSkeleton.slots[i], attachment = slot.attachment;
+ var slotNode = new cc.Node();
+ slot._slotNode = slotNode;
+
+ if (attachment instanceof spine.RegionAttachment) {
+ spriteName = attachment.region.name;
+ sprite = this._createSprite(slot, attachment);
+ slot.currentSprite = sprite;
+ slot.currentSpriteName = spriteName;
+ slotNode.addChild(sprite);
+ } else if (attachment instanceof spine.MeshAttachment) {
+ //todo for mesh
+ }
+ }
+};
+
+var loaded = function (sprite, texture, attachment) {
+ var rendererObject = attachment.region;
+ var rect = new cc.Rect(rendererObject.x, rendererObject.y, rendererObject.width, rendererObject.height);
+ sprite.initWithTexture(texture, rect, rendererObject.rotate, false);
+ sprite._rect.width = attachment.width;
+ sprite._rect.height = attachment.height;
+ sprite.setContentSize(attachment.width, attachment.height);
+ sprite.setRotation(-attachment.rotation);
+ sprite.setScale(rendererObject.width / rendererObject.originalWidth * attachment.scaleX,
+ rendererObject.height / rendererObject.originalHeight * attachment.scaleY);
+};
+
+proto._createSprite = function (slot, attachment) {
+ var rendererObject = attachment.region;
+ var texture = rendererObject.texture.getRealTexture();
+ var sprite = new cc.Sprite();
+ if (texture.isLoaded()) {
+ loaded(sprite, texture, attachment);
+ } else {
+ texture.addEventListener('load', function () {
+ loaded(sprite, texture, attachment);
+ }, this);
+ }
+ slot.sprites = slot.sprites || {};
+ slot.sprites[rendererObject.name] = sprite;
+ return sprite;
+};
+
+proto._updateChild = function () {
+ var locSkeleton = this._node._skeleton, slots = locSkeleton.slots;
+ var color = this._displayedColor, opacity = this._displayedOpacity;
+ var i, n, selSprite, ax, ay;
+
+ var slot, attachment, slotNode;
+ for (i = 0, n = slots.length; i < n; i++) {
+ slot = slots[i];
+ attachment = slot.attachment;
+ slotNode = slot._slotNode;
+ if (!attachment) {
+ slotNode.setVisible(false);
+ continue;
+ }
+ if (attachment instanceof spine.RegionAttachment) {
+ if (attachment.region) {
+ if (!slot.currentSpriteName || slot.currentSpriteName !== attachment.name) {
+ var spriteName = attachment.region.name;
+ if (slot.currentSprite !== undefined)
+ slot.currentSprite.setVisible(false);
+ slot.sprites = slot.sprites || {};
+ if (slot.sprites[spriteName] !== undefined)
+ slot.sprites[spriteName].setVisible(true);
+ else {
+ var sprite = this._createSprite(slot, attachment);
+ slotNode.addChild(sprite);
}
+ slot.currentSprite = slot.sprites[spriteName];
+ slot.currentSpriteName = spriteName;
}
- var bone = slot.bone;
- if (attachment.region.offsetX === 0 && attachment.region.offsetY === 0) {
- ax = attachment.x;
- ay = attachment.y;
- }
- else {
- //var regionScaleX = attachment.width / attachment.regionOriginalWidth * attachment.scaleX;
- //ax = attachment.x + attachment.regionOffsetX * regionScaleX - (attachment.width * attachment.scaleX - attachment.regionWidth * regionScaleX) / 2;
- ax = (attachment.offset[0] + attachment.offset[4]) * 0.5;
- ay = (attachment.offset[1] + attachment.offset[5]) * 0.5;
- }
- slotNode.setPosition(bone.worldX + ax * bone.a + ay * bone.b, bone.worldY + ax * bone.c + ay * bone.d);
- slotNode.setScale(bone.getWorldScaleX(), bone.getWorldScaleY());
-
- //set the color and opacity
- selSprite = slot.currentSprite;
- selSprite._flippedX = bone.skeleton.flipX;
- selSprite._flippedY = bone.skeleton.flipY;
- if (selSprite._flippedY || selSprite._flippedX) {
- slotNode.setRotation(bone.getWorldRotationX());
- selSprite.setRotation(attachment.rotation);
- } else {
- slotNode.setRotation(-bone.getWorldRotationX());
- selSprite.setRotation(-attachment.rotation);
- }
-
- //hack for sprite
- selSprite._renderCmd._displayedOpacity = 0 | (opacity * slot.color.a);
- var r = 0 | (color.r * slot.color.r), g = 0 | (color.g * slot.color.g), b = 0 | (color.b * slot.color.b);
- selSprite.setColor(cc.color(r, g, b));
- selSprite._renderCmd._updateColor();
- } else if (attachment instanceof spine.MeshAttachment) {
- //todo for mesh
+ }
+ var bone = slot.bone;
+ if (attachment.region.offsetX === 0 && attachment.region.offsetY === 0) {
+ ax = attachment.x;
+ ay = attachment.y;
+ }
+ else {
+ //var regionScaleX = attachment.width / attachment.regionOriginalWidth * attachment.scaleX;
+ //ax = attachment.x + attachment.regionOffsetX * regionScaleX - (attachment.width * attachment.scaleX - attachment.regionWidth * regionScaleX) / 2;
+ ax = (attachment.offset[0] + attachment.offset[4]) * 0.5;
+ ay = (attachment.offset[1] + attachment.offset[5]) * 0.5;
+ }
+ slotNode.setPosition(bone.worldX + ax * bone.a + ay * bone.b, bone.worldY + ax * bone.c + ay * bone.d);
+ slotNode.setScale(bone.getWorldScaleX(), bone.getWorldScaleY());
+
+ //set the color and opacity
+ selSprite = slot.currentSprite;
+ selSprite._flippedX = bone.skeleton.flipX;
+ selSprite._flippedY = bone.skeleton.flipY;
+ if (selSprite._flippedY || selSprite._flippedX) {
+ slotNode.setRotation(bone.getWorldRotationX());
+ selSprite.setRotation(attachment.rotation);
} else {
- slotNode.setVisible(false);
- continue;
+ slotNode.setRotation(-bone.getWorldRotationX());
+ selSprite.setRotation(-attachment.rotation);
}
- slotNode.setVisible(true);
+
+ //hack for sprite
+ selSprite._renderCmd._displayedOpacity = 0 | (opacity * slot.color.a);
+ var r = 0 | (color.r * slot.color.r), g = 0 | (color.g * slot.color.g), b = 0 | (color.b * slot.color.b);
+ selSprite.setColor(cc.color(r, g, b));
+ selSprite._renderCmd._updateColor();
+ } else if (attachment instanceof spine.MeshAttachment) {
+ // Can not render mesh
+ } else {
+ slotNode.setVisible(false);
+ continue;
}
- };
+ slotNode.setVisible(true);
+ }
+};
+
})();
diff --git a/extensions/spine/CCSkeletonTexture.js b/extensions/spine/CCSkeletonTexture.js
index 997065b339..9250369c30 100644
--- a/extensions/spine/CCSkeletonTexture.js
+++ b/extensions/spine/CCSkeletonTexture.js
@@ -22,7 +22,11 @@
THE SOFTWARE.
****************************************************************************/
-sp.SkeletonTexture = cc.Class.extend({
+sp.SkeletonTexture = function (image) {
+ sp.spine.Texture.call(this, image);
+};
+cc.inherits(sp.SkeletonTexture, sp.spine.Texture);
+cc.extend(sp.SkeletonTexture.prototype, {
name: 'sp.SkeletonTexture',
_texture: null,
@@ -60,9 +64,4 @@ sp.SkeletonTexture = cc.Class.extend({
cc.glBindTexture2D(this._texture);
}
}
-});
-
-var proto = sp.SkeletonTexture.prototype;
-cc.extend(proto, spine.Texture.prototype);
-// proto.constructor = spine.Texture;
-
+});
\ No newline at end of file
diff --git a/extensions/spine/CCSkeletonWebGLRenderCmd.js b/extensions/spine/CCSkeletonWebGLRenderCmd.js
index e9fc27601a..535e4c0ac5 100644
--- a/extensions/spine/CCSkeletonWebGLRenderCmd.js
+++ b/extensions/spine/CCSkeletonWebGLRenderCmd.js
@@ -23,289 +23,325 @@
****************************************************************************/
(function () {
- sp.Skeleton.WebGLRenderCmd = function (renderableObject) {
- this._rootCtor(renderableObject);
- this._needDraw = true;
- this._matrix = new cc.math.Matrix4();
- this._matrix.identity();
- this.vertexType = cc.renderer.VertexType.CUSTOM;
- this.setShaderProgram(cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLOR));
- };
- var proto = sp.Skeleton.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
- proto.constructor = sp.Skeleton.WebGLRenderCmd;
-
- proto.uploadData = function (f32buffer, ui32buffer, vertexDataOffset){
+var spine = sp.spine;
+
+sp.Skeleton.WebGLRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = true;
+ this._matrix = new cc.math.Matrix4();
+ this._matrix.identity();
+ this._currTexture = null;
+ this._currBlendFunc = {};
+ this.vertexType = cc.renderer.VertexType.CUSTOM;
+ this.setShaderProgram(cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLOR));
+};
+
+var proto = sp.Skeleton.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+proto.constructor = sp.Skeleton.WebGLRenderCmd;
+
+proto.uploadData = function (f32buffer, ui32buffer, vertexDataOffset){
+ var node = this._node;
+ var color = this._displayedColor, locSkeleton = node._skeleton;
+
+ var attachment, slot, i, n;
+ var premultiAlpha = node._premultipliedAlpha;
+
+ locSkeleton.r = color.r / 255;
+ locSkeleton.g = color.g / 255;
+ locSkeleton.b = color.b / 255;
+ locSkeleton.a = this._displayedOpacity / 255;
+ if (premultiAlpha) {
+ locSkeleton.r *= locSkeleton.a;
+ locSkeleton.g *= locSkeleton.a;
+ locSkeleton.b *= locSkeleton.a;
+ }
+
+ var debugSlotsInfo = null;
+ if (this._node._debugSlots) {
+ debugSlotsInfo = [];
+ }
+
+ for (i = 0, n = locSkeleton.drawOrder.length; i < n; i++) {
+ slot = locSkeleton.drawOrder[i];
+ if (!slot.attachment)
+ continue;
+ attachment = slot.attachment;
+
+ // get the vertices length
+ var vertCount = 0;
+ if (attachment instanceof spine.RegionAttachment) {
+ vertCount = 6; // a quad = two triangles = six vertices
+ }
+ else if (attachment instanceof spine.MeshAttachment) {
+ vertCount = attachment.regionUVs.length / 2;
+ }
+ else {
+ continue;
+ }
- // rendering the cached data first
- cc.renderer._batchRendering();
- vertexDataOffset = 0;
+ // no vertices to render
+ if (vertCount === 0) {
+ continue;
+ }
- var node = this._node;
- var color = node.getColor(), locSkeleton = node._skeleton;
+ var regionTextureAtlas = node.getTextureAtlas(attachment);
- var textureAtlas, attachment, slot, i, n;
- var premultiAlpha = node._premultipliedAlpha;
- var blendMode = -1;
- var dataInited = false;
- var cachedVertices = 0;
+ // Broken for changing batch info
+ this._currTexture = regionTextureAtlas.texture.getRealTexture();
+ var batchBroken = cc.renderer._updateBatchedInfo(this._currTexture, this._getBlendFunc(slot.data.blendMode, premultiAlpha), this._glProgramState);
- var wt = this._worldTransform, mat = this._matrix.mat;
- mat[0] = wt.a;
- mat[4] = wt.c;
- mat[12] = wt.tx;
- mat[1] = wt.b;
- mat[5] = wt.d;
- mat[13] = wt.ty;
+ // keep the same logic with RendererWebGL.js, avoid vertex data overflow
+ var uploadAll = vertexDataOffset / 6 + vertCount > (cc.BATCH_VERTEX_COUNT - 200) * 0.5;
+ // Broken for vertex data overflow
+ if (!batchBroken && uploadAll) {
+ // render the cached data
+ cc.renderer._batchRendering();
+ batchBroken = true;
+ }
+ if (batchBroken) {
+ vertexDataOffset = 0;
+ }
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._matrix);
- locSkeleton.r = color.r / 255;
- locSkeleton.g = color.g / 255;
- locSkeleton.b = color.b / 255;
- locSkeleton.a = node.getOpacity() / 255;
- if (premultiAlpha) {
- locSkeleton.r *= locSkeleton.a;
- locSkeleton.g *= locSkeleton.a;
- locSkeleton.b *= locSkeleton.a;
+ // update the vertex buffer
+ var slotDebugPoints = null;
+ if (attachment instanceof spine.RegionAttachment) {
+ slotDebugPoints = this._uploadRegionAttachmentData(attachment, slot, premultiAlpha, f32buffer, ui32buffer, vertexDataOffset);
+ }
+ else if (attachment instanceof spine.MeshAttachment) {
+ this._uploadMeshAttachmentData(attachment, slot, premultiAlpha, f32buffer, ui32buffer, vertexDataOffset);
+ }
+ else {
+ continue;
}
- var debugSlotsInfo = null;
if (this._node._debugSlots) {
- debugSlotsInfo = [];
+ debugSlotsInfo[i] = slotDebugPoints;
}
- for (i = 0, n = locSkeleton.drawOrder.length; i < n; i++) {
- slot = locSkeleton.drawOrder[i];
- if (!slot.attachment)
- continue;
- attachment = slot.attachment;
-
- // get the vertices length
- var vertCount = 0;
- if (attachment instanceof spine.RegionAttachment) {
- vertCount = 6; // a quad = two triangles = six vertices
- }
- else if (attachment instanceof spine.MeshAttachment) {
- vertCount = attachment.regionUVs.length / 2;
- }
- else {
- continue;
- }
-
- // no vertices to render
- if (vertCount === 0) {
- continue;
- }
- var regionTextureAtlas = node.getTextureAtlas(attachment);
- // init data at the first time
- if (!dataInited) {
- textureAtlas = regionTextureAtlas;
- blendMode = slot.data.blendMode;
- cc.renderer._updateBatchedInfo(textureAtlas.texture.getRealTexture(), this._getBlendFunc(blendMode, premultiAlpha), this.getShaderProgram());
- dataInited = true;
- }
+ // update the index buffer
+ if (attachment instanceof spine.RegionAttachment) {
+ cc.renderer._increaseBatchingSize(vertCount, cc.renderer.VertexType.TRIANGLE);
+ } else {
+ cc.renderer._increaseBatchingSize(vertCount, cc.renderer.VertexType.CUSTOM, attachment.triangles);
+ }
- // if data changed or the vertices will be overflow
- if ((cachedVertices + vertCount) * 6 > f32buffer.length ||
- textureAtlas !== regionTextureAtlas ||
- blendMode !== slot.data.blendMode) {
- // render the cached data
- cc.renderer._batchRendering();
- vertexDataOffset = 0;
- cachedVertices = 0;
-
- // update the batched info
- textureAtlas = regionTextureAtlas;
- blendMode = slot.data.blendMode;
- cc.renderer._updateBatchedInfo(textureAtlas.texture.getRealTexture(), this._getBlendFunc(blendMode, premultiAlpha), this.getShaderProgram());
- }
+ // update the index data
+ vertexDataOffset += vertCount * 6;
+ }
- // update the vertex buffer
- var slotDebugPoints = null;
- if (attachment instanceof spine.RegionAttachment) {
- slotDebugPoints = this._uploadRegionAttachmentData(attachment, slot, premultiAlpha, f32buffer, ui32buffer, vertexDataOffset);
- }
- else if (attachment instanceof spine.MeshAttachment) {
- this._uploadMeshAttachmentData(attachment, slot, premultiAlpha, f32buffer, ui32buffer, vertexDataOffset);
- }
- else {
- continue;
- }
-
- if (this._node._debugSlots) {
- debugSlotsInfo[i] = slotDebugPoints;
- }
+ if (node._debugBones || node._debugSlots) {
+ // flush previous vertices
+ cc.renderer._batchRendering();
- // update the index buffer
- if (attachment instanceof spine.RegionAttachment) {
- cc.renderer._increaseBatchingSize(vertCount, cc.renderer.VertexType.TRIANGLE);
- } else {
- cc.renderer._increaseBatchingSize(vertCount, cc.renderer.VertexType.CUSTOM, attachment.triangles);
+ var wt = this._worldTransform, mat = this._matrix.mat;
+ mat[0] = wt.a;
+ mat[4] = wt.c;
+ mat[12] = wt.tx;
+ mat[1] = wt.b;
+ mat[5] = wt.d;
+ mat[13] = wt.ty;
+ cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
+ cc.current_stack.stack.push(cc.current_stack.top);
+ cc.current_stack.top = this._matrix;
+ var drawingUtil = cc._drawingUtil;
+
+ if (node._debugSlots && debugSlotsInfo && debugSlotsInfo.length > 0) {
+ // Slots.
+ drawingUtil.setDrawColor(0, 0, 255, 255);
+ drawingUtil.setLineWidth(1);
+
+ for (i = 0, n = locSkeleton.slots.length; i < n; i++) {
+ var points = debugSlotsInfo[i];
+ if (points) {
+ drawingUtil.drawPoly(points, 4, true);
+ }
}
-
- // update the index data
- cachedVertices += vertCount;
- vertexDataOffset += vertCount * 6;
}
- // render the left vertices
- if (cachedVertices > 0) {
- cc.renderer._batchRendering();
- }
-
- if (node._debugBones || node._debugSlots) {
- cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
- cc.current_stack.stack.push(cc.current_stack.top);
- cc.current_stack.top = this._matrix;
- var drawingUtil = cc._drawingUtil;
-
- if (node._debugSlots && debugSlotsInfo && debugSlotsInfo.length > 0) {
- // Slots.
- drawingUtil.setDrawColor(0, 0, 255, 255);
- drawingUtil.setLineWidth(1);
-
- for (i = 0, n = locSkeleton.slots.length; i < n; i++) {
- var points = debugSlotsInfo[i];
- if (points) {
- drawingUtil.drawPoly(points, 4, true);
- }
- }
+ if (node._debugBones) {
+ // Bone lengths.
+ var bone;
+ drawingUtil.setLineWidth(2);
+ drawingUtil.setDrawColor(255, 0, 0, 255);
+
+ for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
+ bone = locSkeleton.bones[i];
+ var x = bone.data.length * bone.a + bone.worldX;
+ var y = bone.data.length * bone.c + bone.worldY;
+ drawingUtil.drawLine(cc.p(bone.worldX, bone.worldY), cc.p(x, y));
}
- if (node._debugBones) {
- // Bone lengths.
- var bone;
- drawingUtil.setLineWidth(2);
- drawingUtil.setDrawColor(255, 0, 0, 255);
-
- for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
- bone = locSkeleton.bones[i];
- var x = bone.data.length * bone.a + bone.worldX;
- var y = bone.data.length * bone.c + bone.worldY;
- drawingUtil.drawLine(cc.p(bone.worldX, bone.worldY), cc.p(x, y));
- }
-
- // Bone origins.
- drawingUtil.setPointSize(4);
- drawingUtil.setDrawColor(0, 0, 255, 255); // Root bone is blue.
+ // Bone origins.
+ drawingUtil.setPointSize(4);
+ drawingUtil.setDrawColor(0, 0, 255, 255); // Root bone is blue.
- for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
- bone = locSkeleton.bones[i];
- drawingUtil.drawPoint(cc.p(bone.worldX, bone.worldY));
- if (i == 0) {
- drawingUtil.setDrawColor(0, 255, 0, 255);
- }
+ for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
+ bone = locSkeleton.bones[i];
+ drawingUtil.drawPoint(cc.p(bone.worldX, bone.worldY));
+ if (i == 0) {
+ drawingUtil.setDrawColor(0, 255, 0, 255);
}
}
- cc.kmGLPopMatrix();
}
+ cc.kmGLPopMatrix();
+ }
+
+ return 0;
+};
+
+proto._getBlendFunc = function (blendMode, premultiAlpha) {
+ var ret = this._currBlendFunc;
+ switch (blendMode) {
+ case spine.BlendMode.Normal:
+ ret.src = premultiAlpha ? cc.ONE : cc.SRC_ALPHA;
+ ret.dst = cc.ONE_MINUS_SRC_ALPHA;
+ break;
+ case spine.BlendMode.Additive:
+ ret.src = premultiAlpha ? cc.ONE : cc.SRC_ALPHA;
+ ret.dst = cc.ONE;
+ break;
+ case spine.BlendMode.Multiply:
+ ret.src = cc.DST_COLOR;
+ ret.dst = cc.ONE_MINUS_SRC_ALPHA;
+ break;
+ case spine.BlendMode.Screen:
+ ret.src = cc.ONE;
+ ret.dst = cc.ONE_MINUS_SRC_COLOR;
+ break;
+ default:
+ ret = this._node._blendFunc;
+ break;
+ }
+
+ return ret;
+};
+
+proto._createChildFormSkeletonData = function(){};
+
+proto._updateChild = function(){};
+
+proto._uploadRegionAttachmentData = function(attachment, slot, premultipliedAlpha, f32buffer, ui32buffer, vertexDataOffset) {
+ // the vertices in format:
+ // [
+ // X1, Y1, C1R, C1G, C1B, C1A, U1, V1, // bottom left
+ // X2, Y2, C2R, C2G, C2B, C2A, U2, V2, // top left
+ // X3, Y3, C3R, C3G, C3B, C3A, U3, V3, // top right
+ // X4, Y4, C4R, C4G, C4B, C4A, U4, V4 // bottom right
+ // ]
+ //
+ var nodeColor = this._displayedColor;
+ var nodeR = nodeColor.r,
+ nodeG = nodeColor.g,
+ nodeB = nodeColor.b,
+ nodeA = this._displayedOpacity;
+
+ var vertices = spine.Utils.setArraySize(new Array(), 8, 0);
+ attachment.computeWorldVertices(slot.bone, vertices, 0, 2);
+
+ var uvs = attachment.uvs;
+
+ // get the colors data
+ var skeleton = slot.bone.skeleton;
+ var skeletonColor = skeleton.color;
+ var slotColor = slot.color;
+ var regionColor = attachment.color;
+ var alpha = skeletonColor.a * slotColor.a * regionColor.a;
+ var multiplier = premultipliedAlpha ? alpha : 1;
+ var colors = attachment.tempColor;
+ colors.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier,
+ skeletonColor.g * slotColor.g * regionColor.g * multiplier,
+ skeletonColor.b * slotColor.b * regionColor.b * multiplier,
+ alpha);
+
+ var wt = this._worldTransform,
+ wa = wt.a, wb = wt.b, wc = wt.c, wd = wt.d,
+ wx = wt.tx, wy = wt.ty,
+ z = this._node.vertexZ;
+
+ var offset = vertexDataOffset;
+ // generate 6 vertices data (two triangles) from the quad vertices
+ // using two angles : (0, 1, 2) & (0, 2, 3)
+ for (var i = 0; i < 6; i++) {
+ var srcIdx = i < 4 ? i % 3 : i - 2;
+ var vx = vertices[srcIdx * 2],
+ vy = vertices[srcIdx * 2 + 1];
+ var x = vx * wa + vy * wc + wx,
+ y = vx * wb + vy * wd + wy;
+ var r = colors.r * nodeR,
+ g = colors.g * nodeG,
+ b = colors.b * nodeB,
+ a = colors.a * nodeA;
+ var color = ((a<<24) | (b<<16) | (g<<8) | r);
+ f32buffer[offset] = x;
+ f32buffer[offset + 1] = y;
+ f32buffer[offset + 2] = z;
+ ui32buffer[offset + 3] = color;
+ f32buffer[offset + 4] = uvs[srcIdx * 2];
+ f32buffer[offset + 5] = uvs[srcIdx * 2 + 1];
+ offset += 6;
+ }
+
+ if (this._node._debugSlots) {
+ // return the quad points info if debug slot enabled
+ var VERTEX = spine.RegionAttachment;
+ return [
+ cc.p(vertices[VERTEX.OX1], vertices[VERTEX.OY1]),
+ cc.p(vertices[VERTEX.OX2], vertices[VERTEX.OY2]),
+ cc.p(vertices[VERTEX.OX3], vertices[VERTEX.OY3]),
+ cc.p(vertices[VERTEX.OX4], vertices[VERTEX.OY4])
+ ];
+ }
+};
+
+proto._uploadMeshAttachmentData = function(attachment, slot, premultipliedAlpha, f32buffer, ui32buffer, vertexDataOffset) {
+ var wt = this._worldTransform,
+ wa = wt.a, wb = wt.b, wc = wt.c, wd = wt.d,
+ wx = wt.tx, wy = wt.ty,
+ z = this._node.vertexZ;
+ // get the vertex data
+ var verticesLength = attachment.worldVerticesLength;
+ var vertices = spine.Utils.setArraySize(new Array(), verticesLength, 0);
+ attachment.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2);
+
+ var uvs = attachment.uvs;
+
+ // get the colors data
+ var skeleton = slot.bone.skeleton;
+ var skeletonColor = skeleton.color, slotColor = slot.color, meshColor = attachment.color;
+ var alpha = skeletonColor.a * slotColor.a * meshColor.a;
+ var multiplier = premultipliedAlpha ? alpha : 1;
+ var colors = attachment.tempColor;
+ colors.set(skeletonColor.r * slotColor.r * meshColor.r * multiplier,
+ skeletonColor.g * slotColor.g * meshColor.g * multiplier,
+ skeletonColor.b * slotColor.b * meshColor.b * multiplier,
+ alpha);
+
+ var offset = vertexDataOffset;
+ var nodeColor = this._displayedColor;
+ var nodeR = nodeColor.r,
+ nodeG = nodeColor.g,
+ nodeB = nodeColor.b,
+ nodeA = this._displayedOpacity;
+ for (var i = 0, n = vertices.length; i < n; i += 2) {
+ var vx = vertices[i],
+ vy = vertices[i + 1];
+ var x = vx * wa + vy * wb + wx,
+ y = vx * wc + vy * wd + wy;
+ var r = colors.r * nodeR,
+ g = colors.g * nodeG,
+ b = colors.b * nodeB,
+ a = colors.a * nodeA;
+ var color = ((a<<24) | (b<<16) | (g<<8) | r);
+
+ f32buffer[offset] = x;
+ f32buffer[offset + 1] = y;
+ f32buffer[offset + 2] = z;
+ ui32buffer[offset + 3] = color;
+ f32buffer[offset + 4] = uvs[i];
+ f32buffer[offset + 5] = uvs[i + 1];
+ offset += 6;
+ }
+};
- return 0;
- };
-
- proto._getBlendFunc = function (blendMode, premultiAlpha) {
- var ret = {};
- switch (blendMode) {
- case spine.BlendMode.Normal:
- ret.src = premultiAlpha ? cc.ONE : cc.SRC_ALPHA;
- ret.dst = cc.ONE_MINUS_SRC_ALPHA;
- break;
- case spine.BlendMode.Additive:
- ret.src = premultiAlpha ? cc.ONE : cc.SRC_ALPHA;
- ret.dst = cc.ONE;
- break;
- case spine.BlendMode.Multiply:
- ret.src = cc.DST_COLOR;
- ret.dst = cc.ONE_MINUS_SRC_ALPHA;
- break;
- case spine.BlendMode.Screen:
- ret.src = cc.ONE;
- ret.dst = cc.ONE_MINUS_SRC_COLOR;
- break;
- default:
- ret = this._node._blendFunc;
- break;
- }
-
- return ret;
- };
-
- proto._createChildFormSkeletonData = function () {
- };
-
- proto._updateChild = function () {
- };
-
- proto._uploadRegionAttachmentData = function(attachment, slot, premultipliedAlpha, f32buffer, ui32buffer, vertexDataOffset) {
- // the vertices in format:
- // [
- // X1, Y1, C1R, C1G, C1B, C1A, U1, V1, // bottom left
- // X2, Y2, C2R, C2G, C2B, C2A, U2, V2, // top left
- // X3, Y3, C3R, C3G, C3B, C3A, U3, V3, // top right
- // X4, Y4, C4R, C4G, C4B, C4A, U4, V4 // bottom right
- // ]
- //
- var nodeColor = this._displayedColor;
- var nodeR = nodeColor.r,
- nodeG = nodeColor.g,
- nodeB = nodeColor.b,
- nodeA = nodeColor.a;
- var vertices = attachment.updateWorldVertices(slot, premultipliedAlpha);
- var offset = vertexDataOffset;
- // generate 6 vertices data (two triangles) from the quad vertices
- // using two angles : (0, 1, 2) & (0, 2, 3)
- for (var i = 0; i < 6; i++) {
- var srcIdx = i < 4 ? i % 3 : i - 2;
- var r = vertices[srcIdx * 8 + 2] * nodeR,
- g = vertices[srcIdx * 8 + 3] * nodeG,
- b = vertices[srcIdx * 8 + 4] * nodeB,
- a = vertices[srcIdx * 8 + 5] * nodeA;
- var color = ((a<<24) | (b<<16) | (g<<8) | r);
- f32buffer[offset] = vertices[srcIdx * 8];
- f32buffer[offset + 1] = vertices[srcIdx * 8 + 1];
- f32buffer[offset + 2] = this._node.vertexZ;
- ui32buffer[offset + 3] = color;
- f32buffer[offset + 4] = vertices[srcIdx * 8 + 6];
- f32buffer[offset + 5] = vertices[srcIdx * 8 + 7];
- offset += 6;
- }
-
- if (this._node._debugSlots) {
- // return the quad points info if debug slot enabled
- var VERTEX = spine.RegionAttachment;
- return [
- cc.p(vertices[VERTEX.X1], vertices[VERTEX.Y1]),
- cc.p(vertices[VERTEX.X2], vertices[VERTEX.Y2]),
- cc.p(vertices[VERTEX.X3], vertices[VERTEX.Y3]),
- cc.p(vertices[VERTEX.X4], vertices[VERTEX.Y4])
- ];
- }
- };
-
- proto._uploadMeshAttachmentData = function(attachment, slot, premultipliedAlpha, f32buffer, ui32buffer, vertexDataOffset) {
- // get the vertex data
- var vertices = attachment.updateWorldVertices(slot, premultipliedAlpha);
- var offset = vertexDataOffset;
- var nodeColor = this._displayedColor;
- var nodeR = nodeColor.r,
- nodeG = nodeColor.g,
- nodeB = nodeColor.b,
- nodeA = nodeColor.a;
- for (var i = 0, n = vertices.length; i < n; i += 8) {
- var r = vertices[i + 2] * nodeR,
- g = vertices[i + 3] * nodeG,
- b = vertices[i + 4] * nodeB,
- a = vertices[i + 5] * nodeA;
- var color = ((a<<24) | (b<<16) | (g<<8) | r);
-
- f32buffer[offset] = vertices[i];
- f32buffer[offset + 1] = vertices[i + 1];
- f32buffer[offset + 2] = this._node.vertexZ;
- ui32buffer[offset + 3] = color;
- f32buffer[offset + 4] = vertices[i + 6];
- f32buffer[offset + 5] = vertices[i + 7];
- offset += 6;
- }
- };
})();
diff --git a/extensions/spine/LICENSE b/extensions/spine/LICENSE
new file mode 100644
index 0000000000..daceab94a4
--- /dev/null
+++ b/extensions/spine/LICENSE
@@ -0,0 +1,27 @@
+Spine Runtimes Software License v2.5
+
+Copyright (c) 2013-2016, Esoteric Software
+All rights reserved.
+
+You are granted a perpetual, non-exclusive, non-sublicensable, and
+non-transferable license to use, install, execute, and perform the Spine
+Runtimes software and derivative works solely for personal or internal
+use. Without the written permission of Esoteric Software (see Section 2 of
+the Spine Software License Agreement), you may not (a) modify, translate,
+adapt, or develop new applications using the Spine Runtimes or otherwise
+create derivative works or improvements of the Spine Runtimes or (b) remove,
+delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+or other intellectual property or proprietary rights notices on or in the
+Software, including any copy thereof. Redistributions in binary or source
+form must include this license and terms.
+
+THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/extensions/spine/Spine.js b/extensions/spine/Spine.js
index 401e6b84c3..e7c0d894ea 100644
--- a/extensions/spine/Spine.js
+++ b/extensions/spine/Spine.js
@@ -1,8 +1,15 @@
-var __extends = (this && this.__extends) || function (d, b) {
- for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
- function __() { this.constructor = d; }
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-};
+// Spine runtime version 3.6.39
+
+var __extends = (this && this.__extends) || (function () {
+ var extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
var spine;
(function (spine) {
var Animation = (function () {
@@ -15,7 +22,7 @@ var spine;
this.timelines = timelines;
this.duration = duration;
}
- Animation.prototype.apply = function (skeleton, lastTime, time, loop, events, alpha, setupPose, mixingOut) {
+ Animation.prototype.apply = function (skeleton, lastTime, time, loop, events, alpha, pose, direction) {
if (skeleton == null)
throw new Error("skeleton cannot be null.");
if (loop && this.duration != 0) {
@@ -25,7 +32,7 @@ var spine;
}
var timelines = this.timelines;
for (var i = 0, n = timelines.length; i < n; i++)
- timelines[i].apply(skeleton, lastTime, time, events, alpha, setupPose, mixingOut);
+ timelines[i].apply(skeleton, lastTime, time, events, alpha, pose, direction);
};
Animation.binarySearch = function (values, target, step) {
if (step === void 0) { step = 1; }
@@ -53,6 +60,18 @@ var spine;
return Animation;
}());
spine.Animation = Animation;
+ var MixPose;
+ (function (MixPose) {
+ MixPose[MixPose["setup"] = 0] = "setup";
+ MixPose[MixPose["current"] = 1] = "current";
+ MixPose[MixPose["currentLayered"] = 2] = "currentLayered";
+ })(MixPose = spine.MixPose || (spine.MixPose = {}));
+ var MixDirection;
+ (function (MixDirection) {
+ MixDirection[MixDirection["in"] = 0] = "in";
+ MixDirection[MixDirection["out"] = 1] = "out";
+ })(MixDirection = spine.MixDirection || (spine.MixDirection = {}));
+ var TimelineType;
(function (TimelineType) {
TimelineType[TimelineType["rotate"] = 0] = "rotate";
TimelineType[TimelineType["translate"] = 1] = "translate";
@@ -68,8 +87,8 @@ var spine;
TimelineType[TimelineType["pathConstraintPosition"] = 11] = "pathConstraintPosition";
TimelineType[TimelineType["pathConstraintSpacing"] = 12] = "pathConstraintSpacing";
TimelineType[TimelineType["pathConstraintMix"] = 13] = "pathConstraintMix";
- })(spine.TimelineType || (spine.TimelineType = {}));
- var TimelineType = spine.TimelineType;
+ TimelineType[TimelineType["twoColor"] = 14] = "twoColor";
+ })(TimelineType = spine.TimelineType || (spine.TimelineType = {}));
var CurveTimeline = (function () {
function CurveTimeline(frameCount) {
if (frameCount <= 0)
@@ -145,18 +164,19 @@ var spine;
var y = curves[i - 1];
return y + (1 - y) * (percent - x) / (1 - x);
};
- CurveTimeline.LINEAR = 0;
- CurveTimeline.STEPPED = 1;
- CurveTimeline.BEZIER = 2;
- CurveTimeline.BEZIER_SIZE = 10 * 2 - 1;
return CurveTimeline;
}());
+ CurveTimeline.LINEAR = 0;
+ CurveTimeline.STEPPED = 1;
+ CurveTimeline.BEZIER = 2;
+ CurveTimeline.BEZIER_SIZE = 10 * 2 - 1;
spine.CurveTimeline = CurveTimeline;
var RotateTimeline = (function (_super) {
__extends(RotateTimeline, _super);
function RotateTimeline(frameCount) {
- _super.call(this, frameCount);
- this.frames = spine.Utils.newFloatArray(frameCount << 1);
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount << 1);
+ return _this;
}
RotateTimeline.prototype.getPropertyId = function () {
return (TimelineType.rotate << 24) + this.boneIndex;
@@ -166,21 +186,28 @@ var spine;
this.frames[frameIndex] = time;
this.frames[frameIndex + RotateTimeline.ROTATION] = degrees;
};
- RotateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, setupPose, mixingOut) {
+ RotateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
var frames = this.frames;
var bone = skeleton.bones[this.boneIndex];
if (time < frames[0]) {
- if (setupPose)
- bone.rotation = bone.data.rotation;
+ switch (pose) {
+ case MixPose.setup:
+ bone.rotation = bone.data.rotation;
+ return;
+ case MixPose.current:
+ var r_1 = bone.data.rotation - bone.rotation;
+ r_1 -= (16384 - ((16384.499999999996 - r_1 / 360) | 0)) * 360;
+ bone.rotation += r_1 * alpha;
+ }
return;
}
if (time >= frames[frames.length - RotateTimeline.ENTRIES]) {
- if (setupPose)
+ if (pose == MixPose.setup)
bone.rotation = bone.data.rotation + frames[frames.length + RotateTimeline.PREV_ROTATION] * alpha;
else {
- var r_1 = bone.data.rotation + frames[frames.length + RotateTimeline.PREV_ROTATION] - bone.rotation;
- r_1 -= (16384 - ((16384.499999999996 - r_1 / 360) | 0)) * 360;
- bone.rotation += r_1 * alpha;
+ var r_2 = bone.data.rotation + frames[frames.length + RotateTimeline.PREV_ROTATION] - bone.rotation;
+ r_2 -= (16384 - ((16384.499999999996 - r_2 / 360) | 0)) * 360;
+ bone.rotation += r_2 * alpha;
}
return;
}
@@ -191,7 +218,7 @@ var spine;
var r = frames[frame + RotateTimeline.ROTATION] - prevRotation;
r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360;
r = prevRotation + r * percent;
- if (setupPose) {
+ if (pose == MixPose.setup) {
r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360;
bone.rotation = bone.data.rotation + r * alpha;
}
@@ -201,18 +228,19 @@ var spine;
bone.rotation += r * alpha;
}
};
- RotateTimeline.ENTRIES = 2;
- RotateTimeline.PREV_TIME = -2;
- RotateTimeline.PREV_ROTATION = -1;
- RotateTimeline.ROTATION = 1;
return RotateTimeline;
}(CurveTimeline));
+ RotateTimeline.ENTRIES = 2;
+ RotateTimeline.PREV_TIME = -2;
+ RotateTimeline.PREV_ROTATION = -1;
+ RotateTimeline.ROTATION = 1;
spine.RotateTimeline = RotateTimeline;
var TranslateTimeline = (function (_super) {
__extends(TranslateTimeline, _super);
function TranslateTimeline(frameCount) {
- _super.call(this, frameCount);
- this.frames = spine.Utils.newFloatArray(frameCount * TranslateTimeline.ENTRIES);
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * TranslateTimeline.ENTRIES);
+ return _this;
}
TranslateTimeline.prototype.getPropertyId = function () {
return (TimelineType.translate << 24) + this.boneIndex;
@@ -223,13 +251,18 @@ var spine;
this.frames[frameIndex + TranslateTimeline.X] = x;
this.frames[frameIndex + TranslateTimeline.Y] = y;
};
- TranslateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, setupPose, mixingOut) {
+ TranslateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
var frames = this.frames;
var bone = skeleton.bones[this.boneIndex];
if (time < frames[0]) {
- if (setupPose) {
- bone.x = bone.data.x;
- bone.y = bone.data.y;
+ switch (pose) {
+ case MixPose.setup:
+ bone.x = bone.data.x;
+ bone.y = bone.data.y;
+ return;
+ case MixPose.current:
+ bone.x += (bone.data.x - bone.x) * alpha;
+ bone.y += (bone.data.y - bone.y) * alpha;
}
return;
}
@@ -247,7 +280,7 @@ var spine;
x += (frames[frame + TranslateTimeline.X] - x) * percent;
y += (frames[frame + TranslateTimeline.Y] - y) * percent;
}
- if (setupPose) {
+ if (pose == MixPose.setup) {
bone.x = bone.data.x + x * alpha;
bone.y = bone.data.y + y * alpha;
}
@@ -256,30 +289,35 @@ var spine;
bone.y += (bone.data.y + y - bone.y) * alpha;
}
};
- TranslateTimeline.ENTRIES = 3;
- TranslateTimeline.PREV_TIME = -3;
- TranslateTimeline.PREV_X = -2;
- TranslateTimeline.PREV_Y = -1;
- TranslateTimeline.X = 1;
- TranslateTimeline.Y = 2;
return TranslateTimeline;
}(CurveTimeline));
+ TranslateTimeline.ENTRIES = 3;
+ TranslateTimeline.PREV_TIME = -3;
+ TranslateTimeline.PREV_X = -2;
+ TranslateTimeline.PREV_Y = -1;
+ TranslateTimeline.X = 1;
+ TranslateTimeline.Y = 2;
spine.TranslateTimeline = TranslateTimeline;
var ScaleTimeline = (function (_super) {
__extends(ScaleTimeline, _super);
function ScaleTimeline(frameCount) {
- _super.call(this, frameCount);
+ return _super.call(this, frameCount) || this;
}
ScaleTimeline.prototype.getPropertyId = function () {
return (TimelineType.scale << 24) + this.boneIndex;
};
- ScaleTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, setupPose, mixingOut) {
+ ScaleTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
var frames = this.frames;
var bone = skeleton.bones[this.boneIndex];
if (time < frames[0]) {
- if (setupPose) {
- bone.scaleX = bone.data.scaleX;
- bone.scaleY = bone.data.scaleY;
+ switch (pose) {
+ case MixPose.setup:
+ bone.scaleX = bone.data.scaleX;
+ bone.scaleY = bone.data.scaleY;
+ return;
+ case MixPose.current:
+ bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha;
+ bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha;
}
return;
}
@@ -303,7 +341,7 @@ var spine;
}
else {
var bx = 0, by = 0;
- if (setupPose) {
+ if (pose == MixPose.setup) {
bx = bone.data.scaleX;
by = bone.data.scaleY;
}
@@ -311,7 +349,7 @@ var spine;
bx = bone.scaleX;
by = bone.scaleY;
}
- if (mixingOut) {
+ if (direction == MixDirection.out) {
x = Math.abs(x) * spine.MathUtils.signum(bx);
y = Math.abs(y) * spine.MathUtils.signum(by);
}
@@ -329,18 +367,23 @@ var spine;
var ShearTimeline = (function (_super) {
__extends(ShearTimeline, _super);
function ShearTimeline(frameCount) {
- _super.call(this, frameCount);
+ return _super.call(this, frameCount) || this;
}
ShearTimeline.prototype.getPropertyId = function () {
return (TimelineType.shear << 24) + this.boneIndex;
};
- ShearTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, setupPose, mixingOut) {
+ ShearTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
var frames = this.frames;
var bone = skeleton.bones[this.boneIndex];
if (time < frames[0]) {
- if (setupPose) {
- bone.shearX = bone.data.shearX;
- bone.shearY = bone.data.shearY;
+ switch (pose) {
+ case MixPose.setup:
+ bone.shearX = bone.data.shearX;
+ bone.shearY = bone.data.shearY;
+ return;
+ case MixPose.current:
+ bone.shearX += (bone.data.shearX - bone.shearX) * alpha;
+ bone.shearY += (bone.data.shearY - bone.shearY) * alpha;
}
return;
}
@@ -358,7 +401,7 @@ var spine;
x = x + (frames[frame + ShearTimeline.X] - x) * percent;
y = y + (frames[frame + ShearTimeline.Y] - y) * percent;
}
- if (setupPose) {
+ if (pose == MixPose.setup) {
bone.shearX = bone.data.shearX + x * alpha;
bone.shearY = bone.data.shearY + y * alpha;
}
@@ -373,8 +416,9 @@ var spine;
var ColorTimeline = (function (_super) {
__extends(ColorTimeline, _super);
function ColorTimeline(frameCount) {
- _super.call(this, frameCount);
- this.frames = spine.Utils.newFloatArray(frameCount * ColorTimeline.ENTRIES);
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * ColorTimeline.ENTRIES);
+ return _this;
}
ColorTimeline.prototype.getPropertyId = function () {
return (TimelineType.color << 24) + this.slotIndex;
@@ -387,12 +431,18 @@ var spine;
this.frames[frameIndex + ColorTimeline.B] = b;
this.frames[frameIndex + ColorTimeline.A] = a;
};
- ColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, setupPose, mixingOut) {
+ ColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
var slot = skeleton.slots[this.slotIndex];
var frames = this.frames;
if (time < frames[0]) {
- if (setupPose)
- slot.color.setFromColor(slot.data.color);
+ switch (pose) {
+ case MixPose.setup:
+ slot.color.setFromColor(slot.data.color);
+ return;
+ case MixPose.current:
+ var color = slot.color, setup = slot.data.color;
+ color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha, (setup.a - color.a) * alpha);
+ }
return;
}
var r = 0, g = 0, b = 0, a = 0;
@@ -420,24 +470,124 @@ var spine;
slot.color.set(r, g, b, a);
else {
var color = slot.color;
- if (setupPose)
+ if (pose == MixPose.setup)
color.setFromColor(slot.data.color);
color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha);
}
};
- ColorTimeline.ENTRIES = 5;
- ColorTimeline.PREV_TIME = -5;
- ColorTimeline.PREV_R = -4;
- ColorTimeline.PREV_G = -3;
- ColorTimeline.PREV_B = -2;
- ColorTimeline.PREV_A = -1;
- ColorTimeline.R = 1;
- ColorTimeline.G = 2;
- ColorTimeline.B = 3;
- ColorTimeline.A = 4;
return ColorTimeline;
}(CurveTimeline));
+ ColorTimeline.ENTRIES = 5;
+ ColorTimeline.PREV_TIME = -5;
+ ColorTimeline.PREV_R = -4;
+ ColorTimeline.PREV_G = -3;
+ ColorTimeline.PREV_B = -2;
+ ColorTimeline.PREV_A = -1;
+ ColorTimeline.R = 1;
+ ColorTimeline.G = 2;
+ ColorTimeline.B = 3;
+ ColorTimeline.A = 4;
spine.ColorTimeline = ColorTimeline;
+ var TwoColorTimeline = (function (_super) {
+ __extends(TwoColorTimeline, _super);
+ function TwoColorTimeline(frameCount) {
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * TwoColorTimeline.ENTRIES);
+ return _this;
+ }
+ TwoColorTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.twoColor << 24) + this.slotIndex;
+ };
+ TwoColorTimeline.prototype.setFrame = function (frameIndex, time, r, g, b, a, r2, g2, b2) {
+ frameIndex *= TwoColorTimeline.ENTRIES;
+ this.frames[frameIndex] = time;
+ this.frames[frameIndex + TwoColorTimeline.R] = r;
+ this.frames[frameIndex + TwoColorTimeline.G] = g;
+ this.frames[frameIndex + TwoColorTimeline.B] = b;
+ this.frames[frameIndex + TwoColorTimeline.A] = a;
+ this.frames[frameIndex + TwoColorTimeline.R2] = r2;
+ this.frames[frameIndex + TwoColorTimeline.G2] = g2;
+ this.frames[frameIndex + TwoColorTimeline.B2] = b2;
+ };
+ TwoColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
+ var slot = skeleton.slots[this.slotIndex];
+ var frames = this.frames;
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ slot.color.setFromColor(slot.data.color);
+ slot.darkColor.setFromColor(slot.data.darkColor);
+ return;
+ case MixPose.current:
+ var light = slot.color, dark = slot.darkColor, setupLight = slot.data.color, setupDark = slot.data.darkColor;
+ light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha, (setupLight.a - light.a) * alpha);
+ dark.add((setupDark.r - dark.r) * alpha, (setupDark.g - dark.g) * alpha, (setupDark.b - dark.b) * alpha, 0);
+ }
+ return;
+ }
+ var r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0;
+ if (time >= frames[frames.length - TwoColorTimeline.ENTRIES]) {
+ var i = frames.length;
+ r = frames[i + TwoColorTimeline.PREV_R];
+ g = frames[i + TwoColorTimeline.PREV_G];
+ b = frames[i + TwoColorTimeline.PREV_B];
+ a = frames[i + TwoColorTimeline.PREV_A];
+ r2 = frames[i + TwoColorTimeline.PREV_R2];
+ g2 = frames[i + TwoColorTimeline.PREV_G2];
+ b2 = frames[i + TwoColorTimeline.PREV_B2];
+ }
+ else {
+ var frame = Animation.binarySearch(frames, time, TwoColorTimeline.ENTRIES);
+ r = frames[frame + TwoColorTimeline.PREV_R];
+ g = frames[frame + TwoColorTimeline.PREV_G];
+ b = frames[frame + TwoColorTimeline.PREV_B];
+ a = frames[frame + TwoColorTimeline.PREV_A];
+ r2 = frames[frame + TwoColorTimeline.PREV_R2];
+ g2 = frames[frame + TwoColorTimeline.PREV_G2];
+ b2 = frames[frame + TwoColorTimeline.PREV_B2];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / TwoColorTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TwoColorTimeline.PREV_TIME] - frameTime));
+ r += (frames[frame + TwoColorTimeline.R] - r) * percent;
+ g += (frames[frame + TwoColorTimeline.G] - g) * percent;
+ b += (frames[frame + TwoColorTimeline.B] - b) * percent;
+ a += (frames[frame + TwoColorTimeline.A] - a) * percent;
+ r2 += (frames[frame + TwoColorTimeline.R2] - r2) * percent;
+ g2 += (frames[frame + TwoColorTimeline.G2] - g2) * percent;
+ b2 += (frames[frame + TwoColorTimeline.B2] - b2) * percent;
+ }
+ if (alpha == 1) {
+ slot.color.set(r, g, b, a);
+ slot.darkColor.set(r2, g2, b2, 1);
+ }
+ else {
+ var light = slot.color, dark = slot.darkColor;
+ if (pose == MixPose.setup) {
+ light.setFromColor(slot.data.color);
+ dark.setFromColor(slot.data.darkColor);
+ }
+ light.add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha);
+ dark.add((r2 - dark.r) * alpha, (g2 - dark.g) * alpha, (b2 - dark.b) * alpha, 0);
+ }
+ };
+ return TwoColorTimeline;
+ }(CurveTimeline));
+ TwoColorTimeline.ENTRIES = 8;
+ TwoColorTimeline.PREV_TIME = -8;
+ TwoColorTimeline.PREV_R = -7;
+ TwoColorTimeline.PREV_G = -6;
+ TwoColorTimeline.PREV_B = -5;
+ TwoColorTimeline.PREV_A = -4;
+ TwoColorTimeline.PREV_R2 = -3;
+ TwoColorTimeline.PREV_G2 = -2;
+ TwoColorTimeline.PREV_B2 = -1;
+ TwoColorTimeline.R = 1;
+ TwoColorTimeline.G = 2;
+ TwoColorTimeline.B = 3;
+ TwoColorTimeline.A = 4;
+ TwoColorTimeline.R2 = 5;
+ TwoColorTimeline.G2 = 6;
+ TwoColorTimeline.B2 = 7;
+ spine.TwoColorTimeline = TwoColorTimeline;
var AttachmentTimeline = (function () {
function AttachmentTimeline(frameCount) {
this.frames = spine.Utils.newFloatArray(frameCount);
@@ -453,16 +603,16 @@ var spine;
this.frames[frameIndex] = time;
this.attachmentNames[frameIndex] = attachmentName;
};
- AttachmentTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, setupPose, mixingOut) {
+ AttachmentTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
var slot = skeleton.slots[this.slotIndex];
- if (mixingOut && setupPose) {
+ if (direction == MixDirection.out && pose == MixPose.setup) {
var attachmentName_1 = slot.data.attachmentName;
slot.setAttachment(attachmentName_1 == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName_1));
return;
}
var frames = this.frames;
if (time < frames[0]) {
- if (setupPose) {
+ if (pose == MixPose.setup) {
var attachmentName_2 = slot.data.attachmentName;
slot.setAttachment(attachmentName_2 == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName_2));
}
@@ -480,59 +630,87 @@ var spine;
return AttachmentTimeline;
}());
spine.AttachmentTimeline = AttachmentTimeline;
+ var zeros = null;
var DeformTimeline = (function (_super) {
__extends(DeformTimeline, _super);
function DeformTimeline(frameCount) {
- _super.call(this, frameCount);
- this.frames = spine.Utils.newFloatArray(frameCount);
- this.frameVertices = new Array(frameCount);
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount);
+ _this.frameVertices = new Array(frameCount);
+ if (zeros == null)
+ zeros = spine.Utils.newFloatArray(64);
+ return _this;
}
DeformTimeline.prototype.getPropertyId = function () {
- return (TimelineType.deform << 24) + this.slotIndex;
+ return (TimelineType.deform << 27) + +this.attachment.id + this.slotIndex;
};
DeformTimeline.prototype.setFrame = function (frameIndex, time, vertices) {
this.frames[frameIndex] = time;
this.frameVertices[frameIndex] = vertices;
};
- DeformTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, setupPose, mixingOut) {
+ DeformTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
var slot = skeleton.slots[this.slotIndex];
var slotAttachment = slot.getAttachment();
if (!(slotAttachment instanceof spine.VertexAttachment) || !slotAttachment.applyDeform(this.attachment))
return;
- var frames = this.frames;
var verticesArray = slot.attachmentVertices;
- if (time < frames[0]) {
- if (setupPose)
- spine.Utils.setArraySize(verticesArray, 0);
- return;
- }
var frameVertices = this.frameVertices;
var vertexCount = frameVertices[0].length;
- if (verticesArray.length != vertexCount)
- alpha = 1;
var vertices = spine.Utils.setArraySize(verticesArray, vertexCount);
+ var frames = this.frames;
+ if (time < frames[0]) {
+ var vertexAttachment = slotAttachment;
+ switch (pose) {
+ case MixPose.setup:
+ var zeroVertices;
+ if (vertexAttachment.bones == null) {
+ zeroVertices = vertexAttachment.vertices;
+ }
+ else {
+ zeroVertices = zeros;
+ if (zeroVertices.length < vertexCount)
+ zeros = zeroVertices = spine.Utils.newFloatArray(vertexCount);
+ }
+ spine.Utils.arrayCopy(zeroVertices, 0, vertices, 0, vertexCount);
+ return;
+ case MixPose.current:
+ if (alpha == 1)
+ break;
+ if (vertexAttachment.bones == null) {
+ var setupVertices = vertexAttachment.vertices;
+ for (var i = 0; i < vertexCount; i++)
+ vertices[i] += (setupVertices[i] - vertices[i]) * alpha;
+ }
+ else {
+ alpha = 1 - alpha;
+ for (var i = 0; i < vertexCount; i++)
+ vertices[i] *= alpha;
+ }
+ }
+ return;
+ }
if (time >= frames[frames.length - 1]) {
var lastVertices = frameVertices[frames.length - 1];
if (alpha == 1) {
spine.Utils.arrayCopy(lastVertices, 0, vertices, 0, vertexCount);
}
- else if (setupPose) {
+ else if (pose == MixPose.setup) {
var vertexAttachment = slotAttachment;
if (vertexAttachment.bones == null) {
- var setupVertices = vertexAttachment.vertices;
- for (var i = 0; i < vertexCount; i++) {
- var setup = setupVertices[i];
- vertices[i] = setup + (lastVertices[i] - setup) * alpha;
+ var setupVertices_1 = vertexAttachment.vertices;
+ for (var i_1 = 0; i_1 < vertexCount; i_1++) {
+ var setup = setupVertices_1[i_1];
+ vertices[i_1] = setup + (lastVertices[i_1] - setup) * alpha;
}
}
else {
- for (var i = 0; i < vertexCount; i++)
- vertices[i] = lastVertices[i] * alpha;
+ for (var i_2 = 0; i_2 < vertexCount; i_2++)
+ vertices[i_2] = lastVertices[i_2] * alpha;
}
}
else {
- for (var i = 0; i < vertexCount; i++)
- vertices[i] += (lastVertices[i] - vertices[i]) * alpha;
+ for (var i_3 = 0; i_3 < vertexCount; i_3++)
+ vertices[i_3] += (lastVertices[i_3] - vertices[i_3]) * alpha;
}
return;
}
@@ -542,31 +720,31 @@ var spine;
var frameTime = frames[frame];
var percent = this.getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime));
if (alpha == 1) {
- for (var i = 0; i < vertexCount; i++) {
- var prev = prevVertices[i];
- vertices[i] = prev + (nextVertices[i] - prev) * percent;
+ for (var i_4 = 0; i_4 < vertexCount; i_4++) {
+ var prev = prevVertices[i_4];
+ vertices[i_4] = prev + (nextVertices[i_4] - prev) * percent;
}
}
- else if (setupPose) {
+ else if (pose == MixPose.setup) {
var vertexAttachment = slotAttachment;
if (vertexAttachment.bones == null) {
- var setupVertices = vertexAttachment.vertices;
- for (var i = 0; i < vertexCount; i++) {
- var prev = prevVertices[i], setup = setupVertices[i];
- vertices[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha;
+ var setupVertices_2 = vertexAttachment.vertices;
+ for (var i_5 = 0; i_5 < vertexCount; i_5++) {
+ var prev = prevVertices[i_5], setup = setupVertices_2[i_5];
+ vertices[i_5] = setup + (prev + (nextVertices[i_5] - prev) * percent - setup) * alpha;
}
}
else {
- for (var i = 0; i < vertexCount; i++) {
- var prev = prevVertices[i];
- vertices[i] = (prev + (nextVertices[i] - prev) * percent) * alpha;
+ for (var i_6 = 0; i_6 < vertexCount; i_6++) {
+ var prev = prevVertices[i_6];
+ vertices[i_6] = (prev + (nextVertices[i_6] - prev) * percent) * alpha;
}
}
}
else {
- for (var i = 0; i < vertexCount; i++) {
- var prev = prevVertices[i];
- vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha;
+ for (var i_7 = 0; i_7 < vertexCount; i_7++) {
+ var prev = prevVertices[i_7];
+ vertices[i_7] += (prev + (nextVertices[i_7] - prev) * percent - vertices[i_7]) * alpha;
}
}
};
@@ -588,13 +766,13 @@ var spine;
this.frames[frameIndex] = event.time;
this.events[frameIndex] = event;
};
- EventTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, setupPose, mixingOut) {
+ EventTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
if (firedEvents == null)
return;
var frames = this.frames;
var frameCount = this.frames.length;
if (lastTime > time) {
- this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, setupPose, mixingOut);
+ this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, pose, direction);
lastTime = -1;
}
else if (lastTime >= frames[frameCount - 1])
@@ -634,16 +812,16 @@ var spine;
this.frames[frameIndex] = time;
this.drawOrders[frameIndex] = drawOrder;
};
- DrawOrderTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, setupPose, mixingOut) {
+ DrawOrderTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
var drawOrder = skeleton.drawOrder;
var slots = skeleton.slots;
- if (mixingOut && setupPose) {
+ if (direction == MixDirection.out && pose == MixPose.setup) {
spine.Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length);
return;
}
var frames = this.frames;
if (time < frames[0]) {
- if (setupPose)
+ if (pose == MixPose.setup)
spine.Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length);
return;
}
@@ -666,8 +844,9 @@ var spine;
var IkConstraintTimeline = (function (_super) {
__extends(IkConstraintTimeline, _super);
function IkConstraintTimeline(frameCount) {
- _super.call(this, frameCount);
- this.frames = spine.Utils.newFloatArray(frameCount * IkConstraintTimeline.ENTRIES);
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * IkConstraintTimeline.ENTRIES);
+ return _this;
}
IkConstraintTimeline.prototype.getPropertyId = function () {
return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex;
@@ -678,25 +857,30 @@ var spine;
this.frames[frameIndex + IkConstraintTimeline.MIX] = mix;
this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection;
};
- IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, setupPose, mixingOut) {
+ IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
var frames = this.frames;
var constraint = skeleton.ikConstraints[this.ikConstraintIndex];
if (time < frames[0]) {
- if (setupPose) {
- constraint.mix = constraint.data.mix;
- constraint.bendDirection = constraint.data.bendDirection;
+ switch (pose) {
+ case MixPose.setup:
+ constraint.mix = constraint.data.mix;
+ constraint.bendDirection = constraint.data.bendDirection;
+ return;
+ case MixPose.current:
+ constraint.mix += (constraint.data.mix - constraint.mix) * alpha;
+ constraint.bendDirection = constraint.data.bendDirection;
}
return;
}
if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) {
- if (setupPose) {
+ if (pose == MixPose.setup) {
constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha;
- constraint.bendDirection = mixingOut ? constraint.data.bendDirection
+ constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection
: frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
}
else {
constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha;
- if (!mixingOut)
+ if (direction == MixDirection["in"])
constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
}
return;
@@ -705,30 +889,31 @@ var spine;
var mix = frames[frame + IkConstraintTimeline.PREV_MIX];
var frameTime = frames[frame];
var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime));
- if (setupPose) {
+ if (pose == MixPose.setup) {
constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha;
- constraint.bendDirection = mixingOut ? constraint.data.bendDirection : frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
+ constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection : frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
}
else {
constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha;
- if (!mixingOut)
+ if (direction == MixDirection["in"])
constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
}
};
- IkConstraintTimeline.ENTRIES = 3;
- IkConstraintTimeline.PREV_TIME = -3;
- IkConstraintTimeline.PREV_MIX = -2;
- IkConstraintTimeline.PREV_BEND_DIRECTION = -1;
- IkConstraintTimeline.MIX = 1;
- IkConstraintTimeline.BEND_DIRECTION = 2;
return IkConstraintTimeline;
}(CurveTimeline));
+ IkConstraintTimeline.ENTRIES = 3;
+ IkConstraintTimeline.PREV_TIME = -3;
+ IkConstraintTimeline.PREV_MIX = -2;
+ IkConstraintTimeline.PREV_BEND_DIRECTION = -1;
+ IkConstraintTimeline.MIX = 1;
+ IkConstraintTimeline.BEND_DIRECTION = 2;
spine.IkConstraintTimeline = IkConstraintTimeline;
var TransformConstraintTimeline = (function (_super) {
__extends(TransformConstraintTimeline, _super);
function TransformConstraintTimeline(frameCount) {
- _super.call(this, frameCount);
- this.frames = spine.Utils.newFloatArray(frameCount * TransformConstraintTimeline.ENTRIES);
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * TransformConstraintTimeline.ENTRIES);
+ return _this;
}
TransformConstraintTimeline.prototype.getPropertyId = function () {
return (TimelineType.transformConstraint << 24) + this.transformConstraintIndex;
@@ -741,16 +926,23 @@ var spine;
this.frames[frameIndex + TransformConstraintTimeline.SCALE] = scaleMix;
this.frames[frameIndex + TransformConstraintTimeline.SHEAR] = shearMix;
};
- TransformConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, setupPose, mixingOut) {
+ TransformConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
var frames = this.frames;
var constraint = skeleton.transformConstraints[this.transformConstraintIndex];
if (time < frames[0]) {
- if (setupPose) {
- var data = constraint.data;
- constraint.rotateMix = data.rotateMix;
- constraint.translateMix = data.rotateMix;
- constraint.scaleMix = data.scaleMix;
- constraint.shearMix = data.shearMix;
+ var data = constraint.data;
+ switch (pose) {
+ case MixPose.setup:
+ constraint.rotateMix = data.rotateMix;
+ constraint.translateMix = data.translateMix;
+ constraint.scaleMix = data.scaleMix;
+ constraint.shearMix = data.shearMix;
+ return;
+ case MixPose.current:
+ constraint.rotateMix += (data.rotateMix - constraint.rotateMix) * alpha;
+ constraint.translateMix += (data.translateMix - constraint.translateMix) * alpha;
+ constraint.scaleMix += (data.scaleMix - constraint.scaleMix) * alpha;
+ constraint.shearMix += (data.shearMix - constraint.shearMix) * alpha;
}
return;
}
@@ -775,7 +967,7 @@ var spine;
scale += (frames[frame + TransformConstraintTimeline.SCALE] - scale) * percent;
shear += (frames[frame + TransformConstraintTimeline.SHEAR] - shear) * percent;
}
- if (setupPose) {
+ if (pose == MixPose.setup) {
var data = constraint.data;
constraint.rotateMix = data.rotateMix + (rotate - data.rotateMix) * alpha;
constraint.translateMix = data.translateMix + (translate - data.translateMix) * alpha;
@@ -789,24 +981,25 @@ var spine;
constraint.shearMix += (shear - constraint.shearMix) * alpha;
}
};
- TransformConstraintTimeline.ENTRIES = 5;
- TransformConstraintTimeline.PREV_TIME = -5;
- TransformConstraintTimeline.PREV_ROTATE = -4;
- TransformConstraintTimeline.PREV_TRANSLATE = -3;
- TransformConstraintTimeline.PREV_SCALE = -2;
- TransformConstraintTimeline.PREV_SHEAR = -1;
- TransformConstraintTimeline.ROTATE = 1;
- TransformConstraintTimeline.TRANSLATE = 2;
- TransformConstraintTimeline.SCALE = 3;
- TransformConstraintTimeline.SHEAR = 4;
return TransformConstraintTimeline;
}(CurveTimeline));
+ TransformConstraintTimeline.ENTRIES = 5;
+ TransformConstraintTimeline.PREV_TIME = -5;
+ TransformConstraintTimeline.PREV_ROTATE = -4;
+ TransformConstraintTimeline.PREV_TRANSLATE = -3;
+ TransformConstraintTimeline.PREV_SCALE = -2;
+ TransformConstraintTimeline.PREV_SHEAR = -1;
+ TransformConstraintTimeline.ROTATE = 1;
+ TransformConstraintTimeline.TRANSLATE = 2;
+ TransformConstraintTimeline.SCALE = 3;
+ TransformConstraintTimeline.SHEAR = 4;
spine.TransformConstraintTimeline = TransformConstraintTimeline;
var PathConstraintPositionTimeline = (function (_super) {
__extends(PathConstraintPositionTimeline, _super);
function PathConstraintPositionTimeline(frameCount) {
- _super.call(this, frameCount);
- this.frames = spine.Utils.newFloatArray(frameCount * PathConstraintPositionTimeline.ENTRIES);
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * PathConstraintPositionTimeline.ENTRIES);
+ return _this;
}
PathConstraintPositionTimeline.prototype.getPropertyId = function () {
return (TimelineType.pathConstraintPosition << 24) + this.pathConstraintIndex;
@@ -816,12 +1009,17 @@ var spine;
this.frames[frameIndex] = time;
this.frames[frameIndex + PathConstraintPositionTimeline.VALUE] = value;
};
- PathConstraintPositionTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, setupPose, mixingOut) {
+ PathConstraintPositionTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
var frames = this.frames;
var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
if (time < frames[0]) {
- if (setupPose)
- constraint.position = constraint.data.position;
+ switch (pose) {
+ case MixPose.setup:
+ constraint.position = constraint.data.position;
+ return;
+ case MixPose.current:
+ constraint.position += (constraint.data.position - constraint.position) * alpha;
+ }
return;
}
var position = 0;
@@ -834,32 +1032,37 @@ var spine;
var percent = this.getCurvePercent(frame / PathConstraintPositionTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintPositionTimeline.PREV_TIME] - frameTime));
position += (frames[frame + PathConstraintPositionTimeline.VALUE] - position) * percent;
}
- if (setupPose)
+ if (pose == MixPose.setup)
constraint.position = constraint.data.position + (position - constraint.data.position) * alpha;
else
constraint.position += (position - constraint.position) * alpha;
};
- PathConstraintPositionTimeline.ENTRIES = 2;
- PathConstraintPositionTimeline.PREV_TIME = -2;
- PathConstraintPositionTimeline.PREV_VALUE = -1;
- PathConstraintPositionTimeline.VALUE = 1;
return PathConstraintPositionTimeline;
}(CurveTimeline));
+ PathConstraintPositionTimeline.ENTRIES = 2;
+ PathConstraintPositionTimeline.PREV_TIME = -2;
+ PathConstraintPositionTimeline.PREV_VALUE = -1;
+ PathConstraintPositionTimeline.VALUE = 1;
spine.PathConstraintPositionTimeline = PathConstraintPositionTimeline;
var PathConstraintSpacingTimeline = (function (_super) {
__extends(PathConstraintSpacingTimeline, _super);
function PathConstraintSpacingTimeline(frameCount) {
- _super.call(this, frameCount);
+ return _super.call(this, frameCount) || this;
}
PathConstraintSpacingTimeline.prototype.getPropertyId = function () {
return (TimelineType.pathConstraintSpacing << 24) + this.pathConstraintIndex;
};
- PathConstraintSpacingTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, setupPose, mixingOut) {
+ PathConstraintSpacingTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
var frames = this.frames;
var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
if (time < frames[0]) {
- if (setupPose)
- constraint.spacing = constraint.data.spacing;
+ switch (pose) {
+ case MixPose.setup:
+ constraint.spacing = constraint.data.spacing;
+ return;
+ case MixPose.current:
+ constraint.spacing += (constraint.data.spacing - constraint.spacing) * alpha;
+ }
return;
}
var spacing = 0;
@@ -872,7 +1075,7 @@ var spine;
var percent = this.getCurvePercent(frame / PathConstraintSpacingTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintSpacingTimeline.PREV_TIME] - frameTime));
spacing += (frames[frame + PathConstraintSpacingTimeline.VALUE] - spacing) * percent;
}
- if (setupPose)
+ if (pose == MixPose.setup)
constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha;
else
constraint.spacing += (spacing - constraint.spacing) * alpha;
@@ -883,8 +1086,9 @@ var spine;
var PathConstraintMixTimeline = (function (_super) {
__extends(PathConstraintMixTimeline, _super);
function PathConstraintMixTimeline(frameCount) {
- _super.call(this, frameCount);
- this.frames = spine.Utils.newFloatArray(frameCount * PathConstraintMixTimeline.ENTRIES);
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * PathConstraintMixTimeline.ENTRIES);
+ return _this;
}
PathConstraintMixTimeline.prototype.getPropertyId = function () {
return (TimelineType.pathConstraintMix << 24) + this.pathConstraintIndex;
@@ -895,13 +1099,18 @@ var spine;
this.frames[frameIndex + PathConstraintMixTimeline.ROTATE] = rotateMix;
this.frames[frameIndex + PathConstraintMixTimeline.TRANSLATE] = translateMix;
};
- PathConstraintMixTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, setupPose, mixingOut) {
+ PathConstraintMixTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
var frames = this.frames;
var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
if (time < frames[0]) {
- if (setupPose) {
- constraint.rotateMix = constraint.data.rotateMix;
- constraint.translateMix = constraint.data.translateMix;
+ switch (pose) {
+ case MixPose.setup:
+ constraint.rotateMix = constraint.data.rotateMix;
+ constraint.translateMix = constraint.data.translateMix;
+ return;
+ case MixPose.current:
+ constraint.rotateMix += (constraint.data.rotateMix - constraint.rotateMix) * alpha;
+ constraint.translateMix += (constraint.data.translateMix - constraint.translateMix) * alpha;
}
return;
}
@@ -919,7 +1128,7 @@ var spine;
rotate += (frames[frame + PathConstraintMixTimeline.ROTATE] - rotate) * percent;
translate += (frames[frame + PathConstraintMixTimeline.TRANSLATE] - translate) * percent;
}
- if (setupPose) {
+ if (pose == MixPose.setup) {
constraint.rotateMix = constraint.data.rotateMix + (rotate - constraint.data.rotateMix) * alpha;
constraint.translateMix = constraint.data.translateMix + (translate - constraint.data.translateMix) * alpha;
}
@@ -928,14 +1137,14 @@ var spine;
constraint.translateMix += (translate - constraint.translateMix) * alpha;
}
};
- PathConstraintMixTimeline.ENTRIES = 3;
- PathConstraintMixTimeline.PREV_TIME = -3;
- PathConstraintMixTimeline.PREV_ROTATE = -2;
- PathConstraintMixTimeline.PREV_TRANSLATE = -1;
- PathConstraintMixTimeline.ROTATE = 1;
- PathConstraintMixTimeline.TRANSLATE = 2;
return PathConstraintMixTimeline;
}(CurveTimeline));
+ PathConstraintMixTimeline.ENTRIES = 3;
+ PathConstraintMixTimeline.PREV_TIME = -3;
+ PathConstraintMixTimeline.PREV_ROTATE = -2;
+ PathConstraintMixTimeline.PREV_TRANSLATE = -1;
+ PathConstraintMixTimeline.ROTATE = 1;
+ PathConstraintMixTimeline.TRANSLATE = 2;
spine.PathConstraintMixTimeline = PathConstraintMixTimeline;
})(spine || (spine = {}));
var spine;
@@ -947,6 +1156,7 @@ var spine;
this.listeners = new Array();
this.queue = new EventQueue(this);
this.propertyIDs = new spine.IntSet();
+ this.mixingTo = new Array();
this.animationsChanged = false;
this.timeScale = 1;
this.trackEntryPool = new spine.Pool(function () { return new TrackEntry(); });
@@ -984,33 +1194,42 @@ var spine;
continue;
}
}
- else {
- if (current.trackLast >= current.trackEnd && current.mixingFrom == null) {
- tracks[i] = null;
- this.queue.end(current);
- this.disposeNext(current);
- continue;
+ else if (current.trackLast >= current.trackEnd && current.mixingFrom == null) {
+ tracks[i] = null;
+ this.queue.end(current);
+ this.disposeNext(current);
+ continue;
+ }
+ if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) {
+ var from = current.mixingFrom;
+ current.mixingFrom = null;
+ while (from != null) {
+ this.queue.end(from);
+ from = from.mixingFrom;
}
}
- this.updateMixingFrom(current, delta);
current.trackTime += currentDelta;
}
this.queue.drain();
};
- AnimationState.prototype.updateMixingFrom = function (entry, delta) {
- var from = entry.mixingFrom;
+ AnimationState.prototype.updateMixingFrom = function (to, delta) {
+ var from = to.mixingFrom;
if (from == null)
- return;
- this.updateMixingFrom(from, delta);
- if (entry.mixTime >= entry.mixDuration && from.mixingFrom != null && entry.mixTime > 0) {
- entry.mixingFrom = null;
- this.queue.end(from);
- return;
+ return true;
+ var finished = this.updateMixingFrom(from, delta);
+ if (to.mixTime > 0 && (to.mixTime >= to.mixDuration || to.timeScale == 0)) {
+ if (from.totalAlpha == 0 || to.mixDuration == 0) {
+ to.mixingFrom = from.mixingFrom;
+ to.interruptAlpha = from.interruptAlpha;
+ this.queue.end(from);
+ }
+ return finished;
}
from.animationLast = from.nextAnimationLast;
from.trackLast = from.nextTrackLast;
from.trackTime += delta * from.timeScale;
- entry.mixTime += delta * from.timeScale;
+ to.mixTime += delta * to.timeScale;
+ return false;
};
AnimationState.prototype.apply = function (skeleton) {
if (skeleton == null)
@@ -1019,35 +1238,39 @@ var spine;
this._animationsChanged();
var events = this.events;
var tracks = this.tracks;
+ var applied = false;
for (var i = 0, n = tracks.length; i < n; i++) {
var current = tracks[i];
if (current == null || current.delay > 0)
continue;
+ applied = true;
+ var currentPose = i == 0 ? spine.MixPose.current : spine.MixPose.currentLayered;
var mix = current.alpha;
if (current.mixingFrom != null)
- mix *= this.applyMixingFrom(current, skeleton);
- else if (current.trackTime >= current.trackEnd)
+ mix *= this.applyMixingFrom(current, skeleton, currentPose);
+ else if (current.trackTime >= current.trackEnd && current.next == null)
mix = 0;
var animationLast = current.animationLast, animationTime = current.getAnimationTime();
var timelineCount = current.animation.timelines.length;
var timelines = current.animation.timelines;
if (mix == 1) {
for (var ii = 0; ii < timelineCount; ii++)
- timelines[ii].apply(skeleton, animationLast, animationTime, events, 1, true, false);
+ timelines[ii].apply(skeleton, animationLast, animationTime, events, 1, spine.MixPose.setup, spine.MixDirection["in"]);
}
else {
+ var timelineData = current.timelineData;
var firstFrame = current.timelinesRotation.length == 0;
if (firstFrame)
spine.Utils.setArraySize(current.timelinesRotation, timelineCount << 1, null);
var timelinesRotation = current.timelinesRotation;
- var timelinesFirst = current.timelinesFirst;
for (var ii = 0; ii < timelineCount; ii++) {
var timeline = timelines[ii];
+ var pose = timelineData[ii] >= AnimationState.FIRST ? spine.MixPose.setup : currentPose;
if (timeline instanceof spine.RotateTimeline) {
- this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelinesFirst[ii], timelinesRotation, ii << 1, firstFrame);
+ this.applyRotateTimeline(timeline, skeleton, animationTime, mix, pose, timelinesRotation, ii << 1, firstFrame);
}
else
- timeline.apply(skeleton, animationLast, animationTime, events, mix, timelinesFirst[ii], false);
+ timeline.apply(skeleton, animationLast, animationTime, events, mix, pose, spine.MixDirection["in"]);
}
}
this.queueEvents(current, animationTime);
@@ -1056,16 +1279,17 @@ var spine;
current.nextTrackLast = current.trackTime;
}
this.queue.drain();
+ return applied;
};
- AnimationState.prototype.applyMixingFrom = function (entry, skeleton) {
- var from = entry.mixingFrom;
+ AnimationState.prototype.applyMixingFrom = function (to, skeleton, currentPose) {
+ var from = to.mixingFrom;
if (from.mixingFrom != null)
- this.applyMixingFrom(from, skeleton);
+ this.applyMixingFrom(from, skeleton, currentPose);
var mix = 0;
- if (entry.mixDuration == 0)
+ if (to.mixDuration == 0)
mix = 1;
else {
- mix = entry.mixTime / entry.mixDuration;
+ mix = to.mixTime / to.mixDuration;
if (mix > 1)
mix = 1;
}
@@ -1074,46 +1298,67 @@ var spine;
var animationLast = from.animationLast, animationTime = from.getAnimationTime();
var timelineCount = from.animation.timelines.length;
var timelines = from.animation.timelines;
- var timelinesFirst = from.timelinesFirst;
- var alpha = from.alpha * entry.mixAlpha * (1 - mix);
+ var timelineData = from.timelineData;
+ var timelineDipMix = from.timelineDipMix;
var firstFrame = from.timelinesRotation.length == 0;
if (firstFrame)
spine.Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null);
var timelinesRotation = from.timelinesRotation;
+ var pose;
+ var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha = 0;
+ from.totalAlpha = 0;
for (var i = 0; i < timelineCount; i++) {
var timeline = timelines[i];
- var setupPose = timelinesFirst[i];
- if (timeline instanceof spine.RotateTimeline)
- this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, setupPose, timelinesRotation, i << 1, firstFrame);
- else {
- if (!setupPose) {
+ switch (timelineData[i]) {
+ case AnimationState.SUBSEQUENT:
if (!attachments && timeline instanceof spine.AttachmentTimeline)
continue;
if (!drawOrder && timeline instanceof spine.DrawOrderTimeline)
continue;
- }
- timeline.apply(skeleton, animationLast, animationTime, events, alpha, setupPose, true);
+ pose = currentPose;
+ alpha = alphaMix;
+ break;
+ case AnimationState.FIRST:
+ pose = spine.MixPose.setup;
+ alpha = alphaMix;
+ break;
+ case AnimationState.DIP:
+ pose = spine.MixPose.setup;
+ alpha = alphaDip;
+ break;
+ default:
+ pose = spine.MixPose.setup;
+ alpha = alphaDip;
+ var dipMix = timelineDipMix[i];
+ alpha *= Math.max(0, 1 - dipMix.mixTime / dipMix.mixDuration);
+ break;
+ }
+ from.totalAlpha += alpha;
+ if (timeline instanceof spine.RotateTimeline)
+ this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, pose, timelinesRotation, i << 1, firstFrame);
+ else {
+ timeline.apply(skeleton, animationLast, animationTime, events, alpha, pose, spine.MixDirection.out);
}
}
- if (entry.mixDuration > 0)
- this.queueEvents(from, animationTime);
+ if (to.mixDuration > 0)
+ this.queueEvents(from, animationTime);
this.events.length = 0;
from.nextAnimationLast = animationTime;
from.nextTrackLast = from.trackTime;
return mix;
};
- AnimationState.prototype.applyRotateTimeline = function (timeline, skeleton, time, alpha, setupPose, timelinesRotation, i, firstFrame) {
+ AnimationState.prototype.applyRotateTimeline = function (timeline, skeleton, time, alpha, pose, timelinesRotation, i, firstFrame) {
if (firstFrame)
timelinesRotation[i] = 0;
if (alpha == 1) {
- timeline.apply(skeleton, 0, time, null, 1, setupPose, false);
+ timeline.apply(skeleton, 0, time, null, 1, pose, spine.MixDirection["in"]);
return;
}
var rotateTimeline = timeline;
var frames = rotateTimeline.frames;
var bone = skeleton.bones[rotateTimeline.boneIndex];
if (time < frames[0]) {
- if (setupPose)
+ if (pose == spine.MixPose.setup)
bone.rotation = bone.data.rotation;
return;
}
@@ -1130,7 +1375,7 @@ var spine;
r2 = prevRotation + r2 * percent + bone.data.rotation;
r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360;
}
- var r1 = setupPose ? bone.data.rotation : bone.rotation;
+ var r1 = pose == spine.MixPose.setup ? bone.data.rotation : bone.rotation;
var total = 0, diff = r2 - r1;
if (diff == 0) {
total = timelinesRotation[i];
@@ -1187,11 +1432,12 @@ var spine;
}
};
AnimationState.prototype.clearTracks = function () {
+ var oldDrainDisabled = this.queue.drainDisabled;
this.queue.drainDisabled = true;
for (var i = 0, n = this.tracks.length; i < n; i++)
this.clearTrack(i);
this.tracks.length = 0;
- this.queue.drainDisabled = false;
+ this.queue.drainDisabled = oldDrainDisabled;
this.queue.drain();
};
AnimationState.prototype.clearTrack = function (trackIndex) {
@@ -1222,9 +1468,9 @@ var spine;
this.queue.interrupt(from);
current.mixingFrom = from;
current.mixTime = 0;
- from.timelinesRotation.length = 0;
if (from.mixingFrom != null && from.mixDuration > 0)
- current.mixAlpha *= Math.min(from.mixTime / from.mixDuration, 1);
+ current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration);
+ from.timelinesRotation.length = 0;
}
this.queue.start(current);
};
@@ -1303,13 +1549,14 @@ var spine;
return entry;
};
AnimationState.prototype.setEmptyAnimations = function (mixDuration) {
+ var oldDrainDisabled = this.queue.drainDisabled;
this.queue.drainDisabled = true;
for (var i = 0, n = this.tracks.length; i < n; i++) {
var current = this.tracks[i];
if (current != null)
this.setEmptyAnimation(current.trackIndex, mixDuration);
}
- this.queue.drainDisabled = false;
+ this.queue.drainDisabled = oldDrainDisabled;
this.queue.drain();
};
AnimationState.prototype.expandToIndex = function (index) {
@@ -1338,7 +1585,7 @@ var spine;
entry.trackEnd = Number.MAX_VALUE;
entry.timeScale = 1;
entry.alpha = 1;
- entry.mixAlpha = 1;
+ entry.interruptAlpha = 1;
entry.mixTime = 0;
entry.mixDuration = last == null ? 0 : this.data.getMix(last.animation, animation);
return entry;
@@ -1354,50 +1601,14 @@ var spine;
AnimationState.prototype._animationsChanged = function () {
this.animationsChanged = false;
var propertyIDs = this.propertyIDs;
- var i = 0, n = this.tracks.length;
propertyIDs.clear();
- for (; i < n; i++) {
- var entry = this.tracks[i];
- if (entry == null)
- continue;
- this.setTimelinesFirst(entry);
- i++;
- break;
- }
- for (; i < n; i++) {
+ var mixingTo = this.mixingTo;
+ for (var i = 0, n = this.tracks.length; i < n; i++) {
var entry = this.tracks[i];
if (entry != null)
- this.checkTimelinesFirst(entry);
- }
- };
- AnimationState.prototype.setTimelinesFirst = function (entry) {
- if (entry.mixingFrom != null) {
- this.setTimelinesFirst(entry.mixingFrom);
- this.checkTimelinesUsage(entry, entry.timelinesFirst);
- return;
- }
- var propertyIDs = this.propertyIDs;
- var timelines = entry.animation.timelines;
- var n = timelines.length;
- var usage = spine.Utils.setArraySize(entry.timelinesFirst, n, false);
- for (var i = 0; i < n; i++) {
- propertyIDs.add(timelines[i].getPropertyId());
- usage[i] = true;
+ entry.setTimelineData(null, mixingTo, propertyIDs);
}
};
- AnimationState.prototype.checkTimelinesFirst = function (entry) {
- if (entry.mixingFrom != null)
- this.checkTimelinesFirst(entry.mixingFrom);
- this.checkTimelinesUsage(entry, entry.timelinesFirst);
- };
- AnimationState.prototype.checkTimelinesUsage = function (entry, usageArray) {
- var propertyIDs = this.propertyIDs;
- var timelines = entry.animation.timelines;
- var n = timelines.length;
- var usage = spine.Utils.setArraySize(usageArray, n);
- for (var i = 0; i < n; i++)
- usage[i] = propertyIDs.add(timelines[i].getPropertyId());
- };
AnimationState.prototype.getCurrent = function (trackIndex) {
if (trackIndex >= this.tracks.length)
return null;
@@ -1419,13 +1630,18 @@ var spine;
AnimationState.prototype.clearListenerNotifications = function () {
this.queue.clear();
};
- AnimationState.emptyAnimation = new spine.Animation("