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("", [], 0); return AnimationState; }()); + AnimationState.emptyAnimation = new spine.Animation("", [], 0); + AnimationState.SUBSEQUENT = 0; + AnimationState.FIRST = 1; + AnimationState.DIP = 2; + AnimationState.DIP_MIX = 3; spine.AnimationState = AnimationState; var TrackEntry = (function () { function TrackEntry() { - this.timelinesFirst = new Array(); + this.timelineData = new Array(); + this.timelineDipMix = new Array(); this.timelinesRotation = new Array(); } TrackEntry.prototype.reset = function () { @@ -1433,9 +1649,52 @@ var spine; this.mixingFrom = null; this.animation = null; this.listener = null; - this.timelinesFirst.length = 0; + this.timelineData.length = 0; + this.timelineDipMix.length = 0; this.timelinesRotation.length = 0; }; + TrackEntry.prototype.setTimelineData = function (to, mixingToArray, propertyIDs) { + if (to != null) + mixingToArray.push(to); + var lastEntry = this.mixingFrom != null ? this.mixingFrom.setTimelineData(this, mixingToArray, propertyIDs) : this; + if (to != null) + mixingToArray.pop(); + var mixingTo = mixingToArray; + var mixingToLast = mixingToArray.length - 1; + var timelines = this.animation.timelines; + var timelinesCount = this.animation.timelines.length; + var timelineData = spine.Utils.setArraySize(this.timelineData, timelinesCount); + this.timelineDipMix.length = 0; + var timelineDipMix = spine.Utils.setArraySize(this.timelineDipMix, timelinesCount); + outer: for (var i = 0; i < timelinesCount; i++) { + var id = timelines[i].getPropertyId(); + if (!propertyIDs.add(id)) + timelineData[i] = AnimationState.SUBSEQUENT; + else if (to == null || !to.hasTimeline(id)) + timelineData[i] = AnimationState.FIRST; + else { + for (var ii = mixingToLast; ii >= 0; ii--) { + var entry = mixingTo[ii]; + if (!entry.hasTimeline(id)) { + if (entry.mixDuration > 0) { + timelineData[i] = AnimationState.DIP_MIX; + timelineDipMix[i] = entry; + continue outer; + } + } + } + timelineData[i] = AnimationState.DIP; + } + } + return lastEntry; + }; + TrackEntry.prototype.hasTimeline = function (id) { + var timelines = this.animation.timelines; + for (var i = 0, n = timelines.length; i < n; i++) + if (timelines[i].getPropertyId() == id) + return true; + return false; + }; TrackEntry.prototype.getAnimationTime = function () { if (this.loop) { var duration = this.animationEnd - this.animationStart; @@ -1555,6 +1814,7 @@ var spine; return EventQueue; }()); spine.EventQueue = EventQueue; + var EventType; (function (EventType) { EventType[EventType["start"] = 0] = "start"; EventType[EventType["interrupt"] = 1] = "interrupt"; @@ -1562,8 +1822,7 @@ var spine; EventType[EventType["dispose"] = 3] = "dispose"; EventType[EventType["complete"] = 4] = "complete"; EventType[EventType["event"] = 5] = "event"; - })(spine.EventType || (spine.EventType = {})); - var EventType = spine.EventType; + })(EventType = spine.EventType || (spine.EventType = {})); var AnimationStateAdapter2 = (function () { function AnimationStateAdapter2() { } @@ -1665,7 +1924,30 @@ var spine; this.toLoad++; var img = new Image(); img.crossOrigin = "anonymous"; + img.onload = function (ev) { + var texture = _this.textureLoader(img); + _this.assets[path] = texture; + _this.toLoad--; + _this.loaded++; + if (success) + success(path, img); + }; + img.onerror = function (ev) { + _this.errors[path] = "Couldn't load image " + path; + _this.toLoad--; + _this.loaded++; + if (error) + error(path, "Couldn't load image " + path); + }; img.src = path; + }; + AssetManager.prototype.loadTextureData = function (path, data, success, error) { + var _this = this; + if (success === void 0) { success = null; } + if (error === void 0) { error = null; } + path = this.pathPrefix + path; + this.toLoad++; + var img = new Image(); img.onload = function (ev) { var texture = _this.textureLoader(img); _this.assets[path] = texture; @@ -1681,6 +1963,7 @@ var spine; if (error) error(path, "Couldn't load image " + path); }; + img.src = data; }; AssetManager.prototype.get = function (path) { path = this.pathPrefix + path; @@ -1753,511 +2036,102 @@ var spine; AtlasAttachmentLoader.prototype.newPathAttachment = function (skin, name) { return new spine.PathAttachment(name); }; + AtlasAttachmentLoader.prototype.newPointAttachment = function (skin, name) { + return new spine.PointAttachment(name); + }; + AtlasAttachmentLoader.prototype.newClippingAttachment = function (skin, name) { + return new spine.ClippingAttachment(name); + }; return AtlasAttachmentLoader; }()); spine.AtlasAttachmentLoader = AtlasAttachmentLoader; })(spine || (spine = {})); var spine; (function (spine) { - var Attachment = (function () { - function Attachment(name) { - if (name == null) - throw new Error("name cannot be null."); - this.name = name; - } - return Attachment; - }()); - spine.Attachment = Attachment; - var VertexAttachment = (function (_super) { - __extends(VertexAttachment, _super); - function VertexAttachment(name) { - _super.call(this, name); - this.worldVerticesLength = 0; + var BlendMode; + (function (BlendMode) { + BlendMode[BlendMode["Normal"] = 0] = "Normal"; + BlendMode[BlendMode["Additive"] = 1] = "Additive"; + BlendMode[BlendMode["Multiply"] = 2] = "Multiply"; + BlendMode[BlendMode["Screen"] = 3] = "Screen"; + })(BlendMode = spine.BlendMode || (spine.BlendMode = {})); +})(spine || (spine = {})); +var spine; +(function (spine) { + var Bone = (function () { + function Bone(data, skeleton, parent) { + this.children = new Array(); + this.x = 0; + this.y = 0; + this.rotation = 0; + this.scaleX = 0; + this.scaleY = 0; + this.shearX = 0; + this.shearY = 0; + this.ax = 0; + this.ay = 0; + this.arotation = 0; + this.ascaleX = 0; + this.ascaleY = 0; + this.ashearX = 0; + this.ashearY = 0; + this.appliedValid = false; + this.a = 0; + this.b = 0; + this.worldX = 0; + this.c = 0; + this.d = 0; + this.worldY = 0; + this.sorted = false; + if (data == null) + throw new Error("data cannot be null."); + if (skeleton == null) + throw new Error("skeleton cannot be null."); + this.data = data; + this.skeleton = skeleton; + this.parent = parent; + this.setToSetupPose(); } - VertexAttachment.prototype.computeWorldVertices = function (slot, worldVertices) { - this.computeWorldVerticesWith(slot, 0, this.worldVerticesLength, worldVertices, 0); + Bone.prototype.update = function () { + this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); }; - VertexAttachment.prototype.computeWorldVerticesWith = function (slot, start, count, worldVertices, offset) { - count += offset; - var skeleton = slot.bone.skeleton; - var deformArray = slot.attachmentVertices; - var vertices = this.vertices; - var bones = this.bones; - if (bones == null) { - if (deformArray.length > 0) - vertices = deformArray; - var bone = slot.bone; - var x = bone.worldX; - var y = bone.worldY; - var a = bone.a, b = bone.b, c = bone.c, d = bone.d; - for (var v_1 = start, w = offset; w < count; v_1 += 2, w += 2) { - var vx = vertices[v_1], vy = vertices[v_1 + 1]; - worldVertices[w] = vx * a + vy * b + x; - worldVertices[w + 1] = vx * c + vy * d + y; + Bone.prototype.updateWorldTransform = function () { + this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); + }; + Bone.prototype.updateWorldTransformWith = function (x, y, rotation, scaleX, scaleY, shearX, shearY) { + this.ax = x; + this.ay = y; + this.arotation = rotation; + this.ascaleX = scaleX; + this.ascaleY = scaleY; + this.ashearX = shearX; + this.ashearY = shearY; + this.appliedValid = true; + var parent = this.parent; + if (parent == null) { + var rotationY = rotation + 90 + shearY; + var la = spine.MathUtils.cosDeg(rotation + shearX) * scaleX; + var lb = spine.MathUtils.cosDeg(rotationY) * scaleY; + var lc = spine.MathUtils.sinDeg(rotation + shearX) * scaleX; + var ld = spine.MathUtils.sinDeg(rotationY) * scaleY; + var skeleton = this.skeleton; + if (skeleton.flipX) { + x = -x; + la = -la; + lb = -lb; } - return; - } - var v = 0, skip = 0; - for (var i = 0; i < start; i += 2) { - var n = bones[v]; - v += n + 1; - skip += n; - } - var skeletonBones = skeleton.bones; - if (deformArray.length == 0) { - for (var w = offset, b = skip * 3; w < count; w += 2) { - var wx = 0, wy = 0; - var n = bones[v++]; - n += v; - for (; v < n; v++, b += 3) { - var bone = skeletonBones[bones[v]]; - var vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2]; - wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight; - wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight; - } - worldVertices[w] = wx; - worldVertices[w + 1] = wy; + if (skeleton.flipY) { + y = -y; + lc = -lc; + ld = -ld; } - } - else { - var deform = deformArray; - for (var w = offset, b = skip * 3, f = skip << 1; w < count; w += 2) { - var wx = 0, wy = 0; - var n = bones[v++]; - n += v; - for (; v < n; v++, b += 3, f += 2) { - var bone = skeletonBones[bones[v]]; - var vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2]; - wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight; - wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight; - } - worldVertices[w] = wx; - worldVertices[w + 1] = wy; - } - } - }; - VertexAttachment.prototype.applyDeform = function (sourceAttachment) { - return this == sourceAttachment; - }; - return VertexAttachment; - }(Attachment)); - spine.VertexAttachment = VertexAttachment; -})(spine || (spine = {})); -var spine; -(function (spine) { - (function (AttachmentType) { - AttachmentType[AttachmentType["Region"] = 0] = "Region"; - AttachmentType[AttachmentType["BoundingBox"] = 1] = "BoundingBox"; - AttachmentType[AttachmentType["Mesh"] = 2] = "Mesh"; - AttachmentType[AttachmentType["LinkedMesh"] = 3] = "LinkedMesh"; - AttachmentType[AttachmentType["Path"] = 4] = "Path"; - })(spine.AttachmentType || (spine.AttachmentType = {})); - var AttachmentType = spine.AttachmentType; -})(spine || (spine = {})); -var spine; -(function (spine) { - var BoundingBoxAttachment = (function (_super) { - __extends(BoundingBoxAttachment, _super); - function BoundingBoxAttachment(name) { - _super.call(this, name); - this.color = new spine.Color(1, 1, 1, 1); - } - return BoundingBoxAttachment; - }(spine.VertexAttachment)); - spine.BoundingBoxAttachment = BoundingBoxAttachment; -})(spine || (spine = {})); -var spine; -(function (spine) { - var MeshAttachment = (function (_super) { - __extends(MeshAttachment, _super); - function MeshAttachment(name) { - _super.call(this, name); - this.color = new spine.Color(1, 1, 1, 1); - this.inheritDeform = false; - this.tempColor = new spine.Color(0, 0, 0, 0); - } - MeshAttachment.prototype.updateUVs = function () { - var regionUVs = this.regionUVs; - var verticesLength = regionUVs.length; - var worldVerticesLength = (verticesLength >> 1) * 8; - if (this.worldVertices == null || this.worldVertices.length != worldVerticesLength) - this.worldVertices = spine.Utils.newFloatArray(worldVerticesLength); - var u = 0, v = 0, width = 0, height = 0; - if (this.region == null) { - u = v = 0; - width = height = 1; - } - else { - u = this.region.u; - v = this.region.v; - width = this.region.u2 - u; - height = this.region.v2 - v; - } - if (this.region.rotate) { - for (var i = 0, w = 6; i < verticesLength; i += 2, w += 8) { - this.worldVertices[w] = u + regionUVs[i + 1] * width; - this.worldVertices[w + 1] = v + height - regionUVs[i] * height; - } - } - else { - for (var i = 0, w = 6; i < verticesLength; i += 2, w += 8) { - this.worldVertices[w] = u + regionUVs[i] * width; - this.worldVertices[w + 1] = v + regionUVs[i + 1] * height; - } - } - }; - MeshAttachment.prototype.updateWorldVertices = function (slot, premultipliedAlpha) { - var skeleton = slot.bone.skeleton; - var skeletonColor = skeleton.color, slotColor = slot.color, meshColor = this.color; - var alpha = skeletonColor.a * slotColor.a * meshColor.a; - var multiplier = premultipliedAlpha ? alpha : 1; - var color = this.tempColor; - color.set(skeletonColor.r * slotColor.r * meshColor.r * multiplier, skeletonColor.g * slotColor.g * meshColor.g * multiplier, skeletonColor.b * slotColor.b * meshColor.b * multiplier, alpha); - var deformArray = slot.attachmentVertices; - var vertices = this.vertices, worldVertices = this.worldVertices; - var bones = this.bones; - if (bones == null) { - var verticesLength = vertices.length; - if (deformArray.length > 0) - vertices = deformArray; - var bone = slot.bone; - var x = bone.worldX; - var y = bone.worldY; - var a = bone.a, b = bone.b, c = bone.c, d = bone.d; - for (var v = 0, w = 0; v < verticesLength; v += 2, w += 8) { - var vx = vertices[v], vy = vertices[v + 1]; - worldVertices[w] = vx * a + vy * b + x; - worldVertices[w + 1] = vx * c + vy * d + y; - worldVertices[w + 2] = color.r; - worldVertices[w + 3] = color.g; - worldVertices[w + 4] = color.b; - worldVertices[w + 5] = color.a; - } - return worldVertices; - } - var skeletonBones = skeleton.bones; - if (deformArray.length == 0) { - for (var w = 0, v = 0, b = 0, n = bones.length; v < n; w += 8) { - var wx = 0, wy = 0; - var nn = bones[v++] + v; - for (; v < nn; v++, b += 3) { - var bone = skeletonBones[bones[v]]; - var vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2]; - wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight; - wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight; - } - worldVertices[w] = wx; - worldVertices[w + 1] = wy; - worldVertices[w + 2] = color.r; - worldVertices[w + 3] = color.g; - worldVertices[w + 4] = color.b; - worldVertices[w + 5] = color.a; - } - } - else { - var deform = deformArray; - for (var w = 0, v = 0, b = 0, f = 0, n = bones.length; v < n; w += 8) { - var wx = 0, wy = 0; - var nn = bones[v++] + v; - for (; v < nn; v++, b += 3, f += 2) { - var bone = skeletonBones[bones[v]]; - var vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2]; - wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight; - wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight; - } - worldVertices[w] = wx; - worldVertices[w + 1] = wy; - worldVertices[w + 2] = color.r; - worldVertices[w + 3] = color.g; - worldVertices[w + 4] = color.b; - worldVertices[w + 5] = color.a; - } - } - return worldVertices; - }; - MeshAttachment.prototype.applyDeform = function (sourceAttachment) { - return this == sourceAttachment || (this.inheritDeform && this.parentMesh == sourceAttachment); - }; - MeshAttachment.prototype.getParentMesh = function () { - return this.parentMesh; - }; - MeshAttachment.prototype.setParentMesh = function (parentMesh) { - this.parentMesh = parentMesh; - if (parentMesh != null) { - this.bones = parentMesh.bones; - this.vertices = parentMesh.vertices; - this.regionUVs = parentMesh.regionUVs; - this.triangles = parentMesh.triangles; - this.hullLength = parentMesh.hullLength; - } - }; - return MeshAttachment; - }(spine.VertexAttachment)); - spine.MeshAttachment = MeshAttachment; -})(spine || (spine = {})); -var spine; -(function (spine) { - var PathAttachment = (function (_super) { - __extends(PathAttachment, _super); - function PathAttachment(name) { - _super.call(this, name); - this.closed = false; - this.constantSpeed = false; - this.color = new spine.Color(1, 1, 1, 1); - } - return PathAttachment; - }(spine.VertexAttachment)); - spine.PathAttachment = PathAttachment; -})(spine || (spine = {})); -var spine; -(function (spine) { - var RegionAttachment = (function (_super) { - __extends(RegionAttachment, _super); - function RegionAttachment(name) { - _super.call(this, name); - this.x = 0; - this.y = 0; - this.scaleX = 1; - this.scaleY = 1; - this.rotation = 0; - this.width = 0; - this.height = 0; - this.color = new spine.Color(1, 1, 1, 1); - this.offset = spine.Utils.newFloatArray(8); - this.vertices = spine.Utils.newFloatArray(8 * 4); - this.tempColor = new spine.Color(1, 1, 1, 1); - } - RegionAttachment.prototype.setRegion = function (region) { - var vertices = this.vertices; - if (region.rotate) { - vertices[RegionAttachment.U2] = region.u; - vertices[RegionAttachment.V2] = region.v2; - vertices[RegionAttachment.U3] = region.u; - vertices[RegionAttachment.V3] = region.v; - vertices[RegionAttachment.U4] = region.u2; - vertices[RegionAttachment.V4] = region.v; - vertices[RegionAttachment.U1] = region.u2; - vertices[RegionAttachment.V1] = region.v2; - } - else { - vertices[RegionAttachment.U1] = region.u; - vertices[RegionAttachment.V1] = region.v2; - vertices[RegionAttachment.U2] = region.u; - vertices[RegionAttachment.V2] = region.v; - vertices[RegionAttachment.U3] = region.u2; - vertices[RegionAttachment.V3] = region.v; - vertices[RegionAttachment.U4] = region.u2; - vertices[RegionAttachment.V4] = region.v2; - } - this.region = region; - }; - RegionAttachment.prototype.updateOffset = function () { - var regionScaleX = this.width / this.region.originalWidth * this.scaleX; - var regionScaleY = this.height / this.region.originalHeight * this.scaleY; - var localX = -this.width / 2 * this.scaleX + this.region.offsetX * regionScaleX; - var localY = -this.height / 2 * this.scaleY + this.region.offsetY * regionScaleY; - var localX2 = localX + this.region.width * regionScaleX; - var localY2 = localY + this.region.height * regionScaleY; - var radians = this.rotation * Math.PI / 180; - var cos = Math.cos(radians); - var sin = Math.sin(radians); - var localXCos = localX * cos + this.x; - var localXSin = localX * sin; - var localYCos = localY * cos + this.y; - var localYSin = localY * sin; - var localX2Cos = localX2 * cos + this.x; - var localX2Sin = localX2 * sin; - var localY2Cos = localY2 * cos + this.y; - var localY2Sin = localY2 * sin; - var offset = this.offset; - offset[RegionAttachment.OX1] = localXCos - localYSin; - offset[RegionAttachment.OY1] = localYCos + localXSin; - offset[RegionAttachment.OX2] = localXCos - localY2Sin; - offset[RegionAttachment.OY2] = localY2Cos + localXSin; - offset[RegionAttachment.OX3] = localX2Cos - localY2Sin; - offset[RegionAttachment.OY3] = localY2Cos + localX2Sin; - offset[RegionAttachment.OX4] = localX2Cos - localYSin; - offset[RegionAttachment.OY4] = localYCos + localX2Sin; - }; - RegionAttachment.prototype.updateWorldVertices = function (slot, premultipliedAlpha) { - var skeleton = slot.bone.skeleton; - var skeletonColor = skeleton.color; - var slotColor = slot.color; - var regionColor = this.color; - var alpha = skeletonColor.a * slotColor.a * regionColor.a; - var multiplier = premultipliedAlpha ? alpha : 1; - var color = this.tempColor; - color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier, skeletonColor.g * slotColor.g * regionColor.g * multiplier, skeletonColor.b * slotColor.b * regionColor.b * multiplier, alpha); - var vertices = this.vertices; - var offset = this.offset; - var bone = slot.bone; - var x = bone.worldX, y = bone.worldY; - var a = bone.a, b = bone.b, c = bone.c, d = bone.d; - var offsetX = 0, offsetY = 0; - offsetX = offset[RegionAttachment.OX1]; - offsetY = offset[RegionAttachment.OY1]; - vertices[RegionAttachment.X1] = offsetX * a + offsetY * b + x; - vertices[RegionAttachment.Y1] = offsetX * c + offsetY * d + y; - vertices[RegionAttachment.C1R] = color.r; - vertices[RegionAttachment.C1G] = color.g; - vertices[RegionAttachment.C1B] = color.b; - vertices[RegionAttachment.C1A] = color.a; - offsetX = offset[RegionAttachment.OX2]; - offsetY = offset[RegionAttachment.OY2]; - vertices[RegionAttachment.X2] = offsetX * a + offsetY * b + x; - vertices[RegionAttachment.Y2] = offsetX * c + offsetY * d + y; - vertices[RegionAttachment.C2R] = color.r; - vertices[RegionAttachment.C2G] = color.g; - vertices[RegionAttachment.C2B] = color.b; - vertices[RegionAttachment.C2A] = color.a; - offsetX = offset[RegionAttachment.OX3]; - offsetY = offset[RegionAttachment.OY3]; - vertices[RegionAttachment.X3] = offsetX * a + offsetY * b + x; - vertices[RegionAttachment.Y3] = offsetX * c + offsetY * d + y; - vertices[RegionAttachment.C3R] = color.r; - vertices[RegionAttachment.C3G] = color.g; - vertices[RegionAttachment.C3B] = color.b; - vertices[RegionAttachment.C3A] = color.a; - offsetX = offset[RegionAttachment.OX4]; - offsetY = offset[RegionAttachment.OY4]; - vertices[RegionAttachment.X4] = offsetX * a + offsetY * b + x; - vertices[RegionAttachment.Y4] = offsetX * c + offsetY * d + y; - vertices[RegionAttachment.C4R] = color.r; - vertices[RegionAttachment.C4G] = color.g; - vertices[RegionAttachment.C4B] = color.b; - vertices[RegionAttachment.C4A] = color.a; - return vertices; - }; - RegionAttachment.OX1 = 0; - RegionAttachment.OY1 = 1; - RegionAttachment.OX2 = 2; - RegionAttachment.OY2 = 3; - RegionAttachment.OX3 = 4; - RegionAttachment.OY3 = 5; - RegionAttachment.OX4 = 6; - RegionAttachment.OY4 = 7; - RegionAttachment.X1 = 0; - RegionAttachment.Y1 = 1; - RegionAttachment.C1R = 2; - RegionAttachment.C1G = 3; - RegionAttachment.C1B = 4; - RegionAttachment.C1A = 5; - RegionAttachment.U1 = 6; - RegionAttachment.V1 = 7; - RegionAttachment.X2 = 8; - RegionAttachment.Y2 = 9; - RegionAttachment.C2R = 10; - RegionAttachment.C2G = 11; - RegionAttachment.C2B = 12; - RegionAttachment.C2A = 13; - RegionAttachment.U2 = 14; - RegionAttachment.V2 = 15; - RegionAttachment.X3 = 16; - RegionAttachment.Y3 = 17; - RegionAttachment.C3R = 18; - RegionAttachment.C3G = 19; - RegionAttachment.C3B = 20; - RegionAttachment.C3A = 21; - RegionAttachment.U3 = 22; - RegionAttachment.V3 = 23; - RegionAttachment.X4 = 24; - RegionAttachment.Y4 = 25; - RegionAttachment.C4R = 26; - RegionAttachment.C4G = 27; - RegionAttachment.C4B = 28; - RegionAttachment.C4A = 29; - RegionAttachment.U4 = 30; - RegionAttachment.V4 = 31; - return RegionAttachment; - }(spine.Attachment)); - spine.RegionAttachment = RegionAttachment; -})(spine || (spine = {})); -var spine; -(function (spine) { - (function (BlendMode) { - BlendMode[BlendMode["Normal"] = 0] = "Normal"; - BlendMode[BlendMode["Additive"] = 1] = "Additive"; - BlendMode[BlendMode["Multiply"] = 2] = "Multiply"; - BlendMode[BlendMode["Screen"] = 3] = "Screen"; - })(spine.BlendMode || (spine.BlendMode = {})); - var BlendMode = spine.BlendMode; -})(spine || (spine = {})); -var spine; -(function (spine) { - var Bone = (function () { - function Bone(data, skeleton, parent) { - this.children = new Array(); - this.x = 0; - this.y = 0; - this.rotation = 0; - this.scaleX = 0; - this.scaleY = 0; - this.shearX = 0; - this.shearY = 0; - this.ax = 0; - this.ay = 0; - this.arotation = 0; - this.ascaleX = 0; - this.ascaleY = 0; - this.ashearX = 0; - this.ashearY = 0; - this.appliedValid = false; - this.a = 0; - this.b = 0; - this.worldX = 0; - this.c = 0; - this.d = 0; - this.worldY = 0; - this.sorted = false; - if (data == null) - throw new Error("data cannot be null."); - if (skeleton == null) - throw new Error("skeleton cannot be null."); - this.data = data; - this.skeleton = skeleton; - this.parent = parent; - this.setToSetupPose(); - } - Bone.prototype.update = function () { - this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); - }; - Bone.prototype.updateWorldTransform = function () { - this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); - }; - Bone.prototype.updateWorldTransformWith = function (x, y, rotation, scaleX, scaleY, shearX, shearY) { - this.ax = x; - this.ay = y; - this.arotation = rotation; - this.ascaleX = scaleX; - this.ascaleY = scaleY; - this.ashearX = shearX; - this.ashearY = shearY; - this.appliedValid = true; - var parent = this.parent; - if (parent == null) { - var rotationY = rotation + 90 + shearY; - var la = spine.MathUtils.cosDeg(rotation + shearX) * scaleX; - var lb = spine.MathUtils.cosDeg(rotationY) * scaleY; - var lc = spine.MathUtils.sinDeg(rotation + shearX) * scaleX; - var ld = spine.MathUtils.sinDeg(rotationY) * scaleY; - var skeleton = this.skeleton; - if (skeleton.flipX) { - x = -x; - la = -la; - lb = -lb; - } - if (skeleton.flipY) { - y = -y; - lc = -lc; - ld = -ld; - } - this.a = la; - this.b = lb; - this.c = lc; - this.d = ld; - this.worldX = x + skeleton.x; - this.worldY = y + skeleton.y; - return; + this.a = la; + this.b = lb; + this.c = lc; + this.d = ld; + this.worldX = x + skeleton.x; + this.worldY = y + skeleton.y; + return; } var pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d; this.worldX = pa * x + pb * y + parent.worldX; @@ -2328,14 +2202,14 @@ var spine; var lb = spine.MathUtils.cosDeg(90 + shearY) * scaleY; var lc = spine.MathUtils.sinDeg(shearX) * scaleX; var ld = spine.MathUtils.sinDeg(90 + shearY) * scaleY; + if (this.data.transformMode != spine.TransformMode.NoScaleOrReflection ? pa * pd - pb * pc < 0 : this.skeleton.flipX != this.skeleton.flipY) { + zb = -zb; + zd = -zd; + } this.a = za * la + zb * lc; this.b = za * lb + zb * ld; this.c = zc * la + zd * lc; this.d = zc * lb + zd * ld; - if (this.data.transformMode != spine.TransformMode.NoScaleOrReflection ? pa * pd - pb * pc < 0 : this.skeleton.flipX != this.skeleton.flipY) { - this.b = -this.b; - this.d = -this.d; - } return; } } @@ -2370,29 +2244,6 @@ var spine; Bone.prototype.getWorldScaleY = function () { return Math.sqrt(this.b * this.b + this.d * this.d); }; - Bone.prototype.worldToLocalRotationX = function () { - var parent = this.parent; - if (parent == null) - return this.arotation; - var pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d, a = this.a, c = this.c; - return Math.atan2(pa * c - pc * a, pd * a - pb * c) * spine.MathUtils.radDeg; - }; - Bone.prototype.worldToLocalRotationY = function () { - var parent = this.parent; - if (parent == null) - return this.arotation; - var pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d, b = this.b, d = this.d; - return Math.atan2(pa * d - pc * b, pd * b - pb * d) * spine.MathUtils.radDeg; - }; - Bone.prototype.rotateWorld = function (degrees) { - var a = this.a, b = this.b, c = this.c, d = this.d; - var cos = spine.MathUtils.cosDeg(degrees), sin = spine.MathUtils.sinDeg(degrees); - this.a = cos * a - sin * c; - this.b = cos * b - sin * d; - this.c = sin * a + cos * c; - this.d = sin * b + cos * d; - this.appliedValid = false; - }; Bone.prototype.updateAppliedTransform = function () { this.appliedValid = true; var parent = this.parent; @@ -2448,6 +2299,23 @@ var spine; local.y = x * this.c + y * this.d + this.worldY; return local; }; + Bone.prototype.worldToLocalRotation = function (worldRotation) { + var sin = spine.MathUtils.sinDeg(worldRotation), cos = spine.MathUtils.cosDeg(worldRotation); + return Math.atan2(this.a * sin - this.c * cos, this.d * cos - this.b * sin) * spine.MathUtils.radDeg; + }; + Bone.prototype.localToWorldRotation = function (localRotation) { + var sin = spine.MathUtils.sinDeg(localRotation), cos = spine.MathUtils.cosDeg(localRotation); + return Math.atan2(cos * this.c + sin * this.d, cos * this.a + sin * this.b) * spine.MathUtils.radDeg; + }; + Bone.prototype.rotateWorld = function (degrees) { + var a = this.a, b = this.b, c = this.c, d = this.d; + var cos = spine.MathUtils.cosDeg(degrees), sin = spine.MathUtils.sinDeg(degrees); + this.a = cos * a - sin * c; + this.b = cos * b - sin * d; + this.c = sin * a + cos * c; + this.d = sin * b + cos * d; + this.appliedValid = false; + }; return Bone; }()); spine.Bone = Bone; @@ -2475,14 +2343,14 @@ var spine; return BoneData; }()); spine.BoneData = BoneData; + var TransformMode; (function (TransformMode) { TransformMode[TransformMode["Normal"] = 0] = "Normal"; TransformMode[TransformMode["OnlyTranslation"] = 1] = "OnlyTranslation"; TransformMode[TransformMode["NoRotationOrReflection"] = 2] = "NoRotationOrReflection"; TransformMode[TransformMode["NoScale"] = 3] = "NoScale"; TransformMode[TransformMode["NoScaleOrReflection"] = 4] = "NoScaleOrReflection"; - })(spine.TransformMode || (spine.TransformMode = {})); - var TransformMode = spine.TransformMode; + })(TransformMode = spine.TransformMode || (spine.TransformMode = {})); })(spine || (spine = {})); var spine; (function (spine) { @@ -2645,37 +2513,26 @@ var spine; break outer; } } - var minAngle = 0, minDist = Number.MAX_VALUE, minX = 0, minY = 0; - var maxAngle = 0, maxDist = 0, maxX = 0, maxY = 0; - x = l1 + a; - d = x * x; - if (d > maxDist) { - maxAngle = 0; - maxDist = d; - maxX = x; - } - x = l1 - a; - d = x * x; - if (d < minDist) { - minAngle = spine.MathUtils.PI; - minDist = d; - minX = x; - } - var angle = Math.acos(-a * l1 / (aa - bb)); - x = a * Math.cos(angle) + l1; - y = b * Math.sin(angle); - d = x * x + y * y; - if (d < minDist) { - minAngle = angle; - minDist = d; - minX = x; - minY = y; - } - if (d > maxDist) { - maxAngle = angle; - maxDist = d; - maxX = x; - maxY = y; + var minAngle = spine.MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0; + var maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0; + c = -a * l1 / (aa - bb); + if (c >= -1 && c <= 1) { + c = Math.acos(c); + x = a * Math.cos(c) + l1; + y = b * Math.sin(c); + d = x * x + y * y; + if (d < minDist) { + minAngle = c; + minDist = d; + minX = x; + minY = y; + } + if (d > maxDist) { + maxAngle = c; + maxDist = d; + maxX = x; + maxY = y; + } } if (dd <= (minDist + maxDist) / 2) { a1 = ta - Math.atan2(minY * bendDir, minX); @@ -2773,11 +2630,14 @@ var spine; lengths = spine.Utils.setArraySize(this.lengths, boneCount); for (var i = 0, n = spacesCount - 1; i < n;) { var bone = bones[i]; - var length_1 = bone.data.length, x = length_1 * bone.a, y = length_1 * bone.c; - length_1 = Math.sqrt(x * x + y * y); + var setupLength = bone.data.length; + if (setupLength == 0) + setupLength = 0.0000001; + var x = setupLength * bone.a, y = setupLength * bone.c; + var length_1 = Math.sqrt(x * x + y * y); if (scale) lengths[i] = length_1; - spaces[++i] = lengthSpacing ? Math.max(0, length_1 + spacing) : spacing; + spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length_1 / setupLength; } } else { @@ -2873,7 +2733,7 @@ var spine; else if (p < 0) { if (prevCurve != PathConstraint.BEFORE) { prevCurve = PathConstraint.BEFORE; - path.computeWorldVerticesWith(target, 2, 4, world, 0); + path.computeWorldVertices(target, 2, 4, world, 0, 2); } this.addBeforePosition(p, world, 0, out, o); continue; @@ -2881,7 +2741,7 @@ var spine; else if (p > pathLength_1) { if (prevCurve != PathConstraint.AFTER) { prevCurve = PathConstraint.AFTER; - path.computeWorldVerticesWith(target, verticesLength - 6, 4, world, 0); + path.computeWorldVertices(target, verticesLength - 6, 4, world, 0, 2); } this.addAfterPosition(p - pathLength_1, world, 0, out, o); continue; @@ -2901,11 +2761,11 @@ var spine; if (curve != prevCurve) { prevCurve = curve; if (closed && curve == curveCount) { - path.computeWorldVerticesWith(target, verticesLength - 4, 4, world, 0); - path.computeWorldVerticesWith(target, 0, 4, world, 4); + path.computeWorldVertices(target, verticesLength - 4, 4, world, 0, 2); + path.computeWorldVertices(target, 0, 4, world, 4, 2); } else - path.computeWorldVerticesWith(target, curve * 6 + 2, 8, world, 0); + path.computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2); } this.addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o, tangents || (i > 0 && space == 0)); } @@ -2914,8 +2774,8 @@ var spine; if (closed) { verticesLength += 2; world = spine.Utils.setArraySize(this.world, verticesLength); - path.computeWorldVerticesWith(target, 2, verticesLength - 4, world, 0); - path.computeWorldVerticesWith(target, 0, 2, world, verticesLength - 4); + path.computeWorldVertices(target, 2, verticesLength - 4, world, 0, 2); + path.computeWorldVertices(target, 0, 2, world, verticesLength - 4, 2); world[verticesLength - 2] = world[0]; world[verticesLength - 1] = world[1]; } @@ -2923,7 +2783,7 @@ var spine; curveCount--; verticesLength -= 4; world = spine.Utils.setArraySize(this.world, verticesLength); - path.computeWorldVerticesWith(target, 2, verticesLength, world, 0); + path.computeWorldVertices(target, 2, verticesLength, world, 0, 2); } var curves = spine.Utils.setArraySize(this.curves, curveCount); var pathLength = 0; @@ -3080,11 +2940,11 @@ var spine; PathConstraint.prototype.getOrder = function () { return this.data.order; }; - PathConstraint.NONE = -1; - PathConstraint.BEFORE = -2; - PathConstraint.AFTER = -3; return PathConstraint; }()); + PathConstraint.NONE = -1; + PathConstraint.BEFORE = -2; + PathConstraint.AFTER = -3; spine.PathConstraint = PathConstraint; })(spine || (spine = {})); var spine; @@ -3098,24 +2958,33 @@ var spine; return PathConstraintData; }()); spine.PathConstraintData = PathConstraintData; + var PositionMode; (function (PositionMode) { PositionMode[PositionMode["Fixed"] = 0] = "Fixed"; PositionMode[PositionMode["Percent"] = 1] = "Percent"; - })(spine.PositionMode || (spine.PositionMode = {})); - var PositionMode = spine.PositionMode; + })(PositionMode = spine.PositionMode || (spine.PositionMode = {})); + var SpacingMode; (function (SpacingMode) { SpacingMode[SpacingMode["Length"] = 0] = "Length"; SpacingMode[SpacingMode["Fixed"] = 1] = "Fixed"; SpacingMode[SpacingMode["Percent"] = 2] = "Percent"; - })(spine.SpacingMode || (spine.SpacingMode = {})); - var SpacingMode = spine.SpacingMode; + })(SpacingMode = spine.SpacingMode || (spine.SpacingMode = {})); + var RotateMode; (function (RotateMode) { RotateMode[RotateMode["Tangent"] = 0] = "Tangent"; RotateMode[RotateMode["Chain"] = 1] = "Chain"; RotateMode[RotateMode["ChainScale"] = 2] = "ChainScale"; - })(spine.RotateMode || (spine.RotateMode = {})); - var RotateMode = spine.RotateMode; + })(RotateMode = spine.RotateMode || (spine.RotateMode = {})); })(spine || (spine = {})); +(function () { + if (!Math.fround) { + Math.fround = (function (array) { + return function (x) { + return array[0] = x, array[0]; + }; + })(new Float32Array(1)); + } +})(); var spine; (function (spine) { var Assets = (function () { @@ -3311,6 +3180,7 @@ var spine; Skeleton.prototype.updateCache = function () { var updateCache = this._updateCache; updateCache.length = 0; + this.updateCacheReset.length = 0; var bones = this.bones; for (var i = 0, n = bones.length; i < n; i++) bones[i].sorted = false; @@ -3368,27 +3238,38 @@ var spine; this.sortPathConstraintAttachment(this.skin, slotIndex, slotBone); if (this.data.defaultSkin != null && this.data.defaultSkin != this.skin) this.sortPathConstraintAttachment(this.data.defaultSkin, slotIndex, slotBone); - for (var ii = 0, nn = this.data.skins.length; ii < nn; ii++) - this.sortPathConstraintAttachment(this.data.skins[ii], slotIndex, slotBone); + for (var i = 0, n = this.data.skins.length; i < n; i++) + this.sortPathConstraintAttachment(this.data.skins[i], slotIndex, slotBone); var attachment = slot.getAttachment(); if (attachment instanceof spine.PathAttachment) this.sortPathConstraintAttachmentWith(attachment, slotBone); var constrained = constraint.bones; var boneCount = constrained.length; - for (var ii = 0; ii < boneCount; ii++) - this.sortBone(constrained[ii]); + for (var i = 0; i < boneCount; i++) + this.sortBone(constrained[i]); this._updateCache.push(constraint); - for (var ii = 0; ii < boneCount; ii++) - this.sortReset(constrained[ii].children); - for (var ii = 0; ii < boneCount; ii++) - constrained[ii].sorted = true; + for (var i = 0; i < boneCount; i++) + this.sortReset(constrained[i].children); + for (var i = 0; i < boneCount; i++) + constrained[i].sorted = true; }; Skeleton.prototype.sortTransformConstraint = function (constraint) { this.sortBone(constraint.target); var constrained = constraint.bones; var boneCount = constrained.length; - for (var ii = 0; ii < boneCount; ii++) - this.sortBone(constrained[ii]); + if (constraint.data.local) { + for (var i = 0; i < boneCount; i++) { + var child = constrained[i]; + this.sortBone(child.parent); + if (!(this._updateCache.indexOf(child) > -1)) + this.updateCacheReset.push(child); + } + } + else { + for (var i = 0; i < boneCount; i++) { + this.sortBone(constrained[i]); + } + } this._updateCache.push(constraint); for (var ii = 0; ii < boneCount; ii++) this.sortReset(constrained[ii].children); @@ -3631,7 +3512,7 @@ var spine; } return null; }; - Skeleton.prototype.getBounds = function (offset, size) { + Skeleton.prototype.getBounds = function (offset, size, temp) { if (offset == null) throw new Error("offset cannot be null."); if (size == null) @@ -3640,14 +3521,22 @@ var spine; var minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY; for (var i = 0, n = drawOrder.length; i < n; i++) { var slot = drawOrder[i]; + var verticesLength = 0; var vertices = null; var attachment = slot.getAttachment(); - if (attachment instanceof spine.RegionAttachment) - vertices = attachment.updateWorldVertices(slot, false); - else if (attachment instanceof spine.MeshAttachment) - vertices = attachment.updateWorldVertices(slot, true); + if (attachment instanceof spine.RegionAttachment) { + verticesLength = 8; + vertices = spine.Utils.setArraySize(temp, verticesLength, 0); + attachment.computeWorldVertices(slot.bone, vertices, 0, 2); + } + else if (attachment instanceof spine.MeshAttachment) { + var mesh = attachment; + verticesLength = mesh.worldVerticesLength; + vertices = spine.Utils.setArraySize(temp, verticesLength, 0); + mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2); + } if (vertices != null) { - for (var ii = 0, nn = vertices.length; ii < nn; ii += 8) { + for (var ii = 0, nn = vertices.length; ii < nn; ii += 2) { var x = vertices[ii], y = vertices[ii + 1]; minX = Math.min(minX, x); minY = Math.min(minY, y); @@ -3702,7 +3591,7 @@ var spine; polygon = spine.Utils.newFloatArray(boundingBox.worldVerticesLength); } polygons.push(polygon); - boundingBox.computeWorldVertices(slot, polygon); + boundingBox.computeWorldVertices(slot, 0, boundingBox.worldVerticesLength, polygon, 0, 2); } } if (updateAabb) { @@ -3833,6 +3722,286 @@ var spine; spine.SkeletonBounds = SkeletonBounds; })(spine || (spine = {})); var spine; +(function (spine) { + var SkeletonClipping = (function () { + function SkeletonClipping() { + this.triangulator = new spine.Triangulator(); + this.clippingPolygon = new Array(); + this.clipOutput = new Array(); + this.clippedVertices = new Array(); + this.clippedTriangles = new Array(); + this.scratch = new Array(); + } + SkeletonClipping.prototype.clipStart = function (slot, clip) { + if (this.clipAttachment != null) + return 0; + this.clipAttachment = clip; + var n = clip.worldVerticesLength; + var vertices = spine.Utils.setArraySize(this.clippingPolygon, n); + clip.computeWorldVertices(slot, 0, n, vertices, 0, 2); + var clippingPolygon = this.clippingPolygon; + SkeletonClipping.makeClockwise(clippingPolygon); + var clippingPolygons = this.clippingPolygons = this.triangulator.decompose(clippingPolygon, this.triangulator.triangulate(clippingPolygon)); + for (var i = 0, n_1 = clippingPolygons.length; i < n_1; i++) { + var polygon = clippingPolygons[i]; + SkeletonClipping.makeClockwise(polygon); + polygon.push(polygon[0]); + polygon.push(polygon[1]); + } + return clippingPolygons.length; + }; + SkeletonClipping.prototype.clipEndWithSlot = function (slot) { + if (this.clipAttachment != null && this.clipAttachment.endSlot == slot.data) + this.clipEnd(); + }; + SkeletonClipping.prototype.clipEnd = function () { + if (this.clipAttachment == null) + return; + this.clipAttachment = null; + this.clippingPolygons = null; + this.clippedVertices.length = 0; + this.clippedTriangles.length = 0; + this.clippingPolygon.length = 0; + }; + SkeletonClipping.prototype.isClipping = function () { + return this.clipAttachment != null; + }; + SkeletonClipping.prototype.clipTriangles = function (vertices, verticesLength, triangles, trianglesLength, uvs, light, dark, twoColor) { + var clipOutput = this.clipOutput, clippedVertices = this.clippedVertices; + var clippedTriangles = this.clippedTriangles; + var polygons = this.clippingPolygons; + var polygonsCount = this.clippingPolygons.length; + var vertexSize = twoColor ? 12 : 8; + var index = 0; + clippedVertices.length = 0; + clippedTriangles.length = 0; + outer: for (var i = 0; i < trianglesLength; i += 3) { + var vertexOffset = triangles[i] << 1; + var x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1]; + var u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1]; + vertexOffset = triangles[i + 1] << 1; + var x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1]; + var u2 = uvs[vertexOffset], v2 = uvs[vertexOffset + 1]; + vertexOffset = triangles[i + 2] << 1; + var x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1]; + var u3 = uvs[vertexOffset], v3 = uvs[vertexOffset + 1]; + for (var p = 0; p < polygonsCount; p++) { + var s = clippedVertices.length; + if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) { + var clipOutputLength = clipOutput.length; + if (clipOutputLength == 0) + continue; + var d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1; + var d = 1 / (d0 * d2 + d1 * (y1 - y3)); + var clipOutputCount = clipOutputLength >> 1; + var clipOutputItems = this.clipOutput; + var clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + clipOutputCount * vertexSize); + for (var ii = 0; ii < clipOutputLength; ii += 2) { + var x = clipOutputItems[ii], y = clipOutputItems[ii + 1]; + clippedVerticesItems[s] = x; + clippedVerticesItems[s + 1] = y; + clippedVerticesItems[s + 2] = light.r; + clippedVerticesItems[s + 3] = light.g; + clippedVerticesItems[s + 4] = light.b; + clippedVerticesItems[s + 5] = light.a; + var c0 = x - x3, c1 = y - y3; + var a = (d0 * c0 + d1 * c1) * d; + var b = (d4 * c0 + d2 * c1) * d; + var c = 1 - a - b; + clippedVerticesItems[s + 6] = u1 * a + u2 * b + u3 * c; + clippedVerticesItems[s + 7] = v1 * a + v2 * b + v3 * c; + if (twoColor) { + clippedVerticesItems[s + 8] = dark.r; + clippedVerticesItems[s + 9] = dark.g; + clippedVerticesItems[s + 10] = dark.b; + clippedVerticesItems[s + 11] = dark.a; + } + s += vertexSize; + } + s = clippedTriangles.length; + var clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2)); + clipOutputCount--; + for (var ii = 1; ii < clipOutputCount; ii++) { + clippedTrianglesItems[s] = index; + clippedTrianglesItems[s + 1] = (index + ii); + clippedTrianglesItems[s + 2] = (index + ii + 1); + s += 3; + } + index += clipOutputCount + 1; + } + else { + var clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + 3 * vertexSize); + clippedVerticesItems[s] = x1; + clippedVerticesItems[s + 1] = y1; + clippedVerticesItems[s + 2] = light.r; + clippedVerticesItems[s + 3] = light.g; + clippedVerticesItems[s + 4] = light.b; + clippedVerticesItems[s + 5] = light.a; + if (!twoColor) { + clippedVerticesItems[s + 6] = u1; + clippedVerticesItems[s + 7] = v1; + clippedVerticesItems[s + 8] = x2; + clippedVerticesItems[s + 9] = y2; + clippedVerticesItems[s + 10] = light.r; + clippedVerticesItems[s + 11] = light.g; + clippedVerticesItems[s + 12] = light.b; + clippedVerticesItems[s + 13] = light.a; + clippedVerticesItems[s + 14] = u2; + clippedVerticesItems[s + 15] = v2; + clippedVerticesItems[s + 16] = x3; + clippedVerticesItems[s + 17] = y3; + clippedVerticesItems[s + 18] = light.r; + clippedVerticesItems[s + 19] = light.g; + clippedVerticesItems[s + 20] = light.b; + clippedVerticesItems[s + 21] = light.a; + clippedVerticesItems[s + 22] = u3; + clippedVerticesItems[s + 23] = v3; + } + else { + clippedVerticesItems[s + 6] = u1; + clippedVerticesItems[s + 7] = v1; + clippedVerticesItems[s + 8] = dark.r; + clippedVerticesItems[s + 9] = dark.g; + clippedVerticesItems[s + 10] = dark.b; + clippedVerticesItems[s + 11] = dark.a; + clippedVerticesItems[s + 12] = x2; + clippedVerticesItems[s + 13] = y2; + clippedVerticesItems[s + 14] = light.r; + clippedVerticesItems[s + 15] = light.g; + clippedVerticesItems[s + 16] = light.b; + clippedVerticesItems[s + 17] = light.a; + clippedVerticesItems[s + 18] = u2; + clippedVerticesItems[s + 19] = v2; + clippedVerticesItems[s + 20] = dark.r; + clippedVerticesItems[s + 21] = dark.g; + clippedVerticesItems[s + 22] = dark.b; + clippedVerticesItems[s + 23] = dark.a; + clippedVerticesItems[s + 24] = x3; + clippedVerticesItems[s + 25] = y3; + clippedVerticesItems[s + 26] = light.r; + clippedVerticesItems[s + 27] = light.g; + clippedVerticesItems[s + 28] = light.b; + clippedVerticesItems[s + 29] = light.a; + clippedVerticesItems[s + 30] = u3; + clippedVerticesItems[s + 31] = v3; + clippedVerticesItems[s + 32] = dark.r; + clippedVerticesItems[s + 33] = dark.g; + clippedVerticesItems[s + 34] = dark.b; + clippedVerticesItems[s + 35] = dark.a; + } + s = clippedTriangles.length; + var clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3); + clippedTrianglesItems[s] = index; + clippedTrianglesItems[s + 1] = (index + 1); + clippedTrianglesItems[s + 2] = (index + 2); + index += 3; + continue outer; + } + } + } + }; + SkeletonClipping.prototype.clip = function (x1, y1, x2, y2, x3, y3, clippingArea, output) { + var originalOutput = output; + var clipped = false; + var input = null; + if (clippingArea.length % 4 >= 2) { + input = output; + output = this.scratch; + } + else + input = this.scratch; + input.length = 0; + input.push(x1); + input.push(y1); + input.push(x2); + input.push(y2); + input.push(x3); + input.push(y3); + input.push(x1); + input.push(y1); + output.length = 0; + var clippingVertices = clippingArea; + var clippingVerticesLast = clippingArea.length - 4; + for (var i = 0;; i += 2) { + var edgeX = clippingVertices[i], edgeY = clippingVertices[i + 1]; + var edgeX2 = clippingVertices[i + 2], edgeY2 = clippingVertices[i + 3]; + var deltaX = edgeX - edgeX2, deltaY = edgeY - edgeY2; + var inputVertices = input; + var inputVerticesLength = input.length - 2, outputStart = output.length; + for (var ii = 0; ii < inputVerticesLength; ii += 2) { + var inputX = inputVertices[ii], inputY = inputVertices[ii + 1]; + var inputX2 = inputVertices[ii + 2], inputY2 = inputVertices[ii + 3]; + var side2 = deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2) > 0; + if (deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2) > 0) { + if (side2) { + output.push(inputX2); + output.push(inputY2); + continue; + } + var c0 = inputY2 - inputY, c2 = inputX2 - inputX; + var ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY)); + output.push(edgeX + (edgeX2 - edgeX) * ua); + output.push(edgeY + (edgeY2 - edgeY) * ua); + } + else if (side2) { + var c0 = inputY2 - inputY, c2 = inputX2 - inputX; + var ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY)); + output.push(edgeX + (edgeX2 - edgeX) * ua); + output.push(edgeY + (edgeY2 - edgeY) * ua); + output.push(inputX2); + output.push(inputY2); + } + clipped = true; + } + if (outputStart == output.length) { + originalOutput.length = 0; + return true; + } + output.push(output[0]); + output.push(output[1]); + if (i == clippingVerticesLast) + break; + var temp = output; + output = input; + output.length = 0; + input = temp; + } + if (originalOutput != output) { + originalOutput.length = 0; + for (var i = 0, n = output.length - 2; i < n; i++) + originalOutput[i] = output[i]; + } + else + originalOutput.length = originalOutput.length - 2; + return clipped; + }; + SkeletonClipping.makeClockwise = function (polygon) { + var vertices = polygon; + var verticeslength = polygon.length; + var area = vertices[verticeslength - 2] * vertices[1] - vertices[0] * vertices[verticeslength - 1], p1x = 0, p1y = 0, p2x = 0, p2y = 0; + for (var i = 0, n = verticeslength - 3; i < n; i += 2) { + p1x = vertices[i]; + p1y = vertices[i + 1]; + p2x = vertices[i + 2]; + p2y = vertices[i + 3]; + area += p1x * p2y - p2x * p1y; + } + if (area < 0) + return; + for (var i = 0, lastX = verticeslength - 2, n = verticeslength >> 1; i < n; i += 2) { + var x = vertices[i], y = vertices[i + 1]; + var other = lastX - i; + vertices[i] = vertices[other]; + vertices[i + 1] = vertices[other + 1]; + vertices[other] = x; + vertices[other + 1] = y; + } + }; + return SkeletonClipping; + }()); + spine.SkeletonClipping = SkeletonClipping; +})(spine || (spine = {})); +var spine; (function (spine) { var SkeletonData = (function () { function SkeletonData() { @@ -4021,6 +4190,11 @@ var spine; var color = this.getValue(slotMap, "color", null); if (color != null) data.color.setFromString(color); + var dark = this.getValue(slotMap, "dark", null); + if (dark != null) { + data.darkColor = new spine.Color(1, 1, 1, 1); + data.darkColor.setFromString(dark); + } data.attachmentName = this.getValue(slotMap, "attachment", null); data.blendMode = SkeletonJson.blendModeFromString(this.getValue(slotMap, "blend", "normal")); skeletonData.slots.push(data); @@ -4063,6 +4237,8 @@ var spine; data.target = skeletonData.findBone(targetName); if (data.target == null) throw new Error("Transform constraint target bone not found: " + targetName); + data.local = this.getValue(constraintMap, "local", false); + data.relative = this.getValue(constraintMap, "relative", false); data.offsetRotation = this.getValue(constraintMap, "rotation", 0); data.offsetX = this.getValue(constraintMap, "x", 0) * scale; data.offsetY = this.getValue(constraintMap, "y", 0) * scale; @@ -4117,7 +4293,7 @@ var spine; throw new Error("Slot not found: " + slotName); var slotMap = skinMap[slotName]; for (var entryName in slotMap) { - var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName); + var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName, skeletonData); if (attachment != null) skin.addAttachment(slotIndex, entryName, attachment); } @@ -4157,7 +4333,7 @@ var spine; } return skeletonData; }; - SkeletonJson.prototype.readAttachment = function (map, skin, slotIndex, name) { + SkeletonJson.prototype.readAttachment = function (map, skin, slotIndex, name, skeletonData) { var scale = this.scale; name = this.getValue(map, "name", name); var type = this.getValue(map, "type", "region"); @@ -4225,13 +4401,43 @@ var spine; this.readVertices(map, path, vertexCount << 1); var lengths = spine.Utils.newArray(vertexCount / 3, 0); for (var i = 0; i < map.lengths.length; i++) - lengths[i++] = map.lengths[i] * scale; + lengths[i] = map.lengths[i] * scale; path.lengths = lengths; var color = this.getValue(map, "color", null); if (color != null) path.color.setFromString(color); return path; } + case "point": { + var point = this.attachmentLoader.newPointAttachment(skin, name); + if (point == null) + return null; + point.x = this.getValue(map, "x", 0) * scale; + point.y = this.getValue(map, "y", 0) * scale; + point.rotation = this.getValue(map, "rotation", 0); + var color = this.getValue(map, "color", null); + if (color != null) + point.color.setFromString(color); + return point; + } + case "clipping": { + var clip = this.attachmentLoader.newClippingAttachment(skin, name); + if (clip == null) + return null; + var end = this.getValue(map, "end", null); + if (end != null) { + var slot = skeletonData.findSlot(end); + if (slot == null) + throw new Error("Clipping end slot not found: " + end); + clip.endSlot = slot; + } + var vertexCount = map.vertexCount; + this.readVertices(map, clip, vertexCount << 1); + var color = this.getValue(map, "color", null); + if (color != null) + clip.color.setFromString(color); + return clip; + } } return null; }; @@ -4239,8 +4445,8 @@ var spine; var scale = this.scale; attachment.worldVerticesLength = verticesLength; var vertices = map.vertices; - var scaledVertices = spine.Utils.toFloatArray(vertices); if (verticesLength == vertices.length) { + var scaledVertices = spine.Utils.toFloatArray(vertices); if (scale != 1) { for (var i = 0, n = vertices.length; i < n; i++) scaledVertices[i] *= scale; @@ -4275,7 +4481,18 @@ var spine; throw new Error("Slot not found: " + slotName); for (var timelineName in slotMap) { var timelineMap = slotMap[timelineName]; - if (timelineName == "color") { + if (timelineName == "attachment") { + var timeline = new spine.AttachmentTimeline(timelineMap.length); + timeline.slotIndex = slotIndex; + var frameIndex = 0; + for (var i = 0; i < timelineMap.length; i++) { + var valueMap = timelineMap[i]; + timeline.setFrame(frameIndex++, valueMap.time, valueMap.name); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); + } + else if (timelineName == "color") { var timeline = new spine.ColorTimeline(timelineMap.length); timeline.slotIndex = slotIndex; var frameIndex = 0; @@ -4290,16 +4507,22 @@ var spine; timelines.push(timeline); duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.ColorTimeline.ENTRIES]); } - else if (timelineName = "attachment") { - var timeline = new spine.AttachmentTimeline(timelineMap.length); + else if (timelineName == "twoColor") { + var timeline = new spine.TwoColorTimeline(timelineMap.length); timeline.slotIndex = slotIndex; var frameIndex = 0; for (var i = 0; i < timelineMap.length; i++) { var valueMap = timelineMap[i]; - timeline.setFrame(frameIndex++, valueMap.time, valueMap.name); + var light = new spine.Color(); + var dark = new spine.Color(); + light.setFromString(valueMap.light); + dark.setFromString(valueMap.dark); + timeline.setFrame(frameIndex, valueMap.time, light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; } timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.TwoColorTimeline.ENTRIES]); } else throw new Error("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")"); @@ -4533,7 +4756,7 @@ var spine; var eventData = skeletonData.findEvent(eventMap.name); if (eventData == null) throw new Error("Event not found: " + eventMap.name); - var event_5 = new spine.Event(eventMap.time, eventData); + var event_5 = new spine.Event(spine.Utils.toSinglePrecision(eventMap.time), eventData); event_5.intValue = this.getValue(eventMap, "int", eventData.intValue); event_5.floatValue = this.getValue(eventMap, "float", eventData.floatValue); event_5.stringValue = this.getValue(eventMap, "string", eventData.stringValue); @@ -4686,6 +4909,7 @@ var spine; this.data = data; this.bone = bone; this.color = new spine.Color(); + this.darkColor = data.darkColor == null ? null : new spine.Color(); this.setToSetupPose(); } Slot.prototype.getAttachment = function () { @@ -4706,6 +4930,8 @@ var spine; }; Slot.prototype.setToSetupPose = function () { this.color.setFromColor(this.data.color); + if (this.darkColor != null) + this.darkColor.setFromColor(this.data.darkColor); if (this.data.attachmentName == null) this.attachment = null; else { @@ -4768,6 +4994,7 @@ var spine; return Texture; }()); spine.Texture = Texture; + var TextureFilter; (function (TextureFilter) { TextureFilter[TextureFilter["Nearest"] = 9728] = "Nearest"; TextureFilter[TextureFilter["Linear"] = 9729] = "Linear"; @@ -4776,14 +5003,13 @@ var spine; TextureFilter[TextureFilter["MipMapLinearNearest"] = 9985] = "MipMapLinearNearest"; TextureFilter[TextureFilter["MipMapNearestLinear"] = 9986] = "MipMapNearestLinear"; TextureFilter[TextureFilter["MipMapLinearLinear"] = 9987] = "MipMapLinearLinear"; - })(spine.TextureFilter || (spine.TextureFilter = {})); - var TextureFilter = spine.TextureFilter; + })(TextureFilter = spine.TextureFilter || (spine.TextureFilter = {})); + var TextureWrap; (function (TextureWrap) { TextureWrap[TextureWrap["MirroredRepeat"] = 33648] = "MirroredRepeat"; TextureWrap[TextureWrap["ClampToEdge"] = 33071] = "ClampToEdge"; TextureWrap[TextureWrap["Repeat"] = 10497] = "Repeat"; - })(spine.TextureWrap || (spine.TextureWrap = {})); - var TextureWrap = spine.TextureWrap; + })(TextureWrap = spine.TextureWrap || (spine.TextureWrap = {})); var TextureRegion = (function () { function TextureRegion() { this.u = 0; @@ -4951,7 +5177,7 @@ var spine; var TextureAtlasRegion = (function (_super) { __extends(TextureAtlasRegion, _super); function TextureAtlasRegion() { - _super.apply(this, arguments); + return _super !== null && _super.apply(this, arguments) || this; } return TextureAtlasRegion; }(spine.TextureRegion)); @@ -4984,6 +5210,20 @@ var spine; this.update(); }; TransformConstraint.prototype.update = function () { + if (this.data.local) { + if (this.data.relative) + this.applyRelativeLocal(); + else + this.applyAbsoluteLocal(); + } + else { + if (this.data.relative) + this.applyRelativeWorld(); + else + this.applyAbsoluteWorld(); + } + }; + TransformConstraint.prototype.applyAbsoluteWorld = function () { var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; var target = this.target; var ta = target.a, tb = target.b, tc = target.c, td = target.d; @@ -5049,6 +5289,132 @@ var spine; bone.appliedValid = false; } }; + TransformConstraint.prototype.applyRelativeWorld = function () { + var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + var target = this.target; + var ta = target.a, tb = target.b, tc = target.c, td = target.d; + var degRadReflect = ta * td - tb * tc > 0 ? spine.MathUtils.degRad : -spine.MathUtils.degRad; + var offsetRotation = this.data.offsetRotation * degRadReflect, offsetShearY = this.data.offsetShearY * degRadReflect; + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + var modified = false; + if (rotateMix != 0) { + var a = bone.a, b = bone.b, c = bone.c, d = bone.d; + var r = Math.atan2(tc, ta) + offsetRotation; + if (r > spine.MathUtils.PI) + r -= spine.MathUtils.PI2; + else if (r < -spine.MathUtils.PI) + r += spine.MathUtils.PI2; + r *= rotateMix; + var cos = Math.cos(r), sin = Math.sin(r); + bone.a = cos * a - sin * c; + bone.b = cos * b - sin * d; + bone.c = sin * a + cos * c; + bone.d = sin * b + cos * d; + modified = true; + } + if (translateMix != 0) { + var temp = this.temp; + target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); + bone.worldX += temp.x * translateMix; + bone.worldY += temp.y * translateMix; + modified = true; + } + if (scaleMix > 0) { + var s = (Math.sqrt(ta * ta + tc * tc) - 1 + this.data.offsetScaleX) * scaleMix + 1; + bone.a *= s; + bone.c *= s; + s = (Math.sqrt(tb * tb + td * td) - 1 + this.data.offsetScaleY) * scaleMix + 1; + bone.b *= s; + bone.d *= s; + modified = true; + } + if (shearMix > 0) { + var r = Math.atan2(td, tb) - Math.atan2(tc, ta); + if (r > spine.MathUtils.PI) + r -= spine.MathUtils.PI2; + else if (r < -spine.MathUtils.PI) + r += spine.MathUtils.PI2; + var b = bone.b, d = bone.d; + r = Math.atan2(d, b) + (r - spine.MathUtils.PI / 2 + offsetShearY) * shearMix; + var s = Math.sqrt(b * b + d * d); + bone.b = Math.cos(r) * s; + bone.d = Math.sin(r) * s; + modified = true; + } + if (modified) + bone.appliedValid = false; + } + }; + TransformConstraint.prototype.applyAbsoluteLocal = function () { + var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + var target = this.target; + if (!target.appliedValid) + target.updateAppliedTransform(); + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + if (!bone.appliedValid) + bone.updateAppliedTransform(); + var rotation = bone.arotation; + if (rotateMix != 0) { + var r = target.arotation - rotation + this.data.offsetRotation; + r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; + rotation += r * rotateMix; + } + var x = bone.ax, y = bone.ay; + if (translateMix != 0) { + x += (target.ax - x + this.data.offsetX) * translateMix; + y += (target.ay - y + this.data.offsetY) * translateMix; + } + var scaleX = bone.ascaleX, scaleY = bone.ascaleY; + if (scaleMix > 0) { + if (scaleX > 0.00001) + scaleX = (scaleX + (target.ascaleX - scaleX + this.data.offsetScaleX) * scaleMix) / scaleX; + if (scaleY > 0.00001) + scaleY = (scaleY + (target.ascaleY - scaleY + this.data.offsetScaleY) * scaleMix) / scaleY; + } + var shearY = bone.ashearY; + if (shearMix > 0) { + var r = target.ashearY - shearY + this.data.offsetShearY; + r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; + bone.shearY += r * shearMix; + } + bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); + } + }; + TransformConstraint.prototype.applyRelativeLocal = function () { + var rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + var target = this.target; + if (!target.appliedValid) + target.updateAppliedTransform(); + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) { + var bone = bones[i]; + if (!bone.appliedValid) + bone.updateAppliedTransform(); + var rotation = bone.arotation; + if (rotateMix != 0) + rotation += (target.arotation + this.data.offsetRotation) * rotateMix; + var x = bone.ax, y = bone.ay; + if (translateMix != 0) { + x += (target.ax + this.data.offsetX) * translateMix; + y += (target.ay + this.data.offsetY) * translateMix; + } + var scaleX = bone.ascaleX, scaleY = bone.ascaleY; + if (scaleMix > 0) { + if (scaleX > 0.00001) + scaleX *= ((target.ascaleX - 1 + this.data.offsetScaleX) * scaleMix) + 1; + if (scaleY > 0.00001) + scaleY *= ((target.ascaleY - 1 + this.data.offsetScaleY) * scaleMix) + 1; + } + var shearY = bone.ashearY; + if (shearMix > 0) + shearY += (target.ashearY + this.data.offsetShearY) * shearMix; + bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); + } + }; TransformConstraint.prototype.getOrder = function () { return this.data.order; }; @@ -5072,13 +5438,227 @@ var spine; this.offsetScaleX = 0; this.offsetScaleY = 0; this.offsetShearY = 0; + this.relative = false; + this.local = false; if (name == null) throw new Error("name cannot be null."); this.name = name; } return TransformConstraintData; }()); - spine.TransformConstraintData = TransformConstraintData; + spine.TransformConstraintData = TransformConstraintData; +})(spine || (spine = {})); +var spine; +(function (spine) { + var Triangulator = (function () { + function Triangulator() { + this.convexPolygons = new Array(); + this.convexPolygonsIndices = new Array(); + this.indicesArray = new Array(); + this.isConcaveArray = new Array(); + this.triangles = new Array(); + this.polygonPool = new spine.Pool(function () { + return new Array(); + }); + this.polygonIndicesPool = new spine.Pool(function () { + return new Array(); + }); + } + Triangulator.prototype.triangulate = function (verticesArray) { + var vertices = verticesArray; + var vertexCount = verticesArray.length >> 1; + var indices = this.indicesArray; + indices.length = 0; + for (var i = 0; i < vertexCount; i++) + indices[i] = i; + var isConcave = this.isConcaveArray; + isConcave.length = 0; + for (var i = 0, n = vertexCount; i < n; ++i) + isConcave[i] = Triangulator.isConcave(i, vertexCount, vertices, indices); + var triangles = this.triangles; + triangles.length = 0; + while (vertexCount > 3) { + var previous = vertexCount - 1, i = 0, next = 1; + while (true) { + outer: if (!isConcave[i]) { + var p1 = indices[previous] << 1, p2 = indices[i] << 1, p3 = indices[next] << 1; + var p1x = vertices[p1], p1y = vertices[p1 + 1]; + var p2x = vertices[p2], p2y = vertices[p2 + 1]; + var p3x = vertices[p3], p3y = vertices[p3 + 1]; + for (var ii = (next + 1) % vertexCount; ii != previous; ii = (ii + 1) % vertexCount) { + if (!isConcave[ii]) + continue; + var v = indices[ii] << 1; + var vx = vertices[v], vy = vertices[v + 1]; + if (Triangulator.positiveArea(p3x, p3y, p1x, p1y, vx, vy)) { + if (Triangulator.positiveArea(p1x, p1y, p2x, p2y, vx, vy)) { + if (Triangulator.positiveArea(p2x, p2y, p3x, p3y, vx, vy)) + break outer; + } + } + } + break; + } + if (next == 0) { + do { + if (!isConcave[i]) + break; + i--; + } while (i > 0); + break; + } + previous = i; + i = next; + next = (next + 1) % vertexCount; + } + triangles.push(indices[(vertexCount + i - 1) % vertexCount]); + triangles.push(indices[i]); + triangles.push(indices[(i + 1) % vertexCount]); + indices.splice(i, 1); + isConcave.splice(i, 1); + vertexCount--; + var previousIndex = (vertexCount + i - 1) % vertexCount; + var nextIndex = i == vertexCount ? 0 : i; + isConcave[previousIndex] = Triangulator.isConcave(previousIndex, vertexCount, vertices, indices); + isConcave[nextIndex] = Triangulator.isConcave(nextIndex, vertexCount, vertices, indices); + } + if (vertexCount == 3) { + triangles.push(indices[2]); + triangles.push(indices[0]); + triangles.push(indices[1]); + } + return triangles; + }; + Triangulator.prototype.decompose = function (verticesArray, triangles) { + var vertices = verticesArray; + var convexPolygons = this.convexPolygons; + this.polygonPool.freeAll(convexPolygons); + convexPolygons.length = 0; + var convexPolygonsIndices = this.convexPolygonsIndices; + this.polygonIndicesPool.freeAll(convexPolygonsIndices); + convexPolygonsIndices.length = 0; + var polygonIndices = this.polygonIndicesPool.obtain(); + polygonIndices.length = 0; + var polygon = this.polygonPool.obtain(); + polygon.length = 0; + var fanBaseIndex = -1, lastWinding = 0; + for (var i = 0, n = triangles.length; i < n; i += 3) { + var t1 = triangles[i] << 1, t2 = triangles[i + 1] << 1, t3 = triangles[i + 2] << 1; + var x1 = vertices[t1], y1 = vertices[t1 + 1]; + var x2 = vertices[t2], y2 = vertices[t2 + 1]; + var x3 = vertices[t3], y3 = vertices[t3 + 1]; + var merged = false; + if (fanBaseIndex == t1) { + var o = polygon.length - 4; + var winding1 = Triangulator.winding(polygon[o], polygon[o + 1], polygon[o + 2], polygon[o + 3], x3, y3); + var winding2 = Triangulator.winding(x3, y3, polygon[0], polygon[1], polygon[2], polygon[3]); + if (winding1 == lastWinding && winding2 == lastWinding) { + polygon.push(x3); + polygon.push(y3); + polygonIndices.push(t3); + merged = true; + } + } + if (!merged) { + if (polygon.length > 0) { + convexPolygons.push(polygon); + convexPolygonsIndices.push(polygonIndices); + } + else { + this.polygonPool.free(polygon); + this.polygonIndicesPool.free(polygonIndices); + } + polygon = this.polygonPool.obtain(); + polygon.length = 0; + polygon.push(x1); + polygon.push(y1); + polygon.push(x2); + polygon.push(y2); + polygon.push(x3); + polygon.push(y3); + polygonIndices = this.polygonIndicesPool.obtain(); + polygonIndices.length = 0; + polygonIndices.push(t1); + polygonIndices.push(t2); + polygonIndices.push(t3); + lastWinding = Triangulator.winding(x1, y1, x2, y2, x3, y3); + fanBaseIndex = t1; + } + } + if (polygon.length > 0) { + convexPolygons.push(polygon); + convexPolygonsIndices.push(polygonIndices); + } + for (var i = 0, n = convexPolygons.length; i < n; i++) { + polygonIndices = convexPolygonsIndices[i]; + if (polygonIndices.length == 0) + continue; + var firstIndex = polygonIndices[0]; + var lastIndex = polygonIndices[polygonIndices.length - 1]; + polygon = convexPolygons[i]; + var o = polygon.length - 4; + var prevPrevX = polygon[o], prevPrevY = polygon[o + 1]; + var prevX = polygon[o + 2], prevY = polygon[o + 3]; + var firstX = polygon[0], firstY = polygon[1]; + var secondX = polygon[2], secondY = polygon[3]; + var winding = Triangulator.winding(prevPrevX, prevPrevY, prevX, prevY, firstX, firstY); + for (var ii = 0; ii < n; ii++) { + if (ii == i) + continue; + var otherIndices = convexPolygonsIndices[ii]; + if (otherIndices.length != 3) + continue; + var otherFirstIndex = otherIndices[0]; + var otherSecondIndex = otherIndices[1]; + var otherLastIndex = otherIndices[2]; + var otherPoly = convexPolygons[ii]; + var x3 = otherPoly[otherPoly.length - 2], y3 = otherPoly[otherPoly.length - 1]; + if (otherFirstIndex != firstIndex || otherSecondIndex != lastIndex) + continue; + var winding1 = Triangulator.winding(prevPrevX, prevPrevY, prevX, prevY, x3, y3); + var winding2 = Triangulator.winding(x3, y3, firstX, firstY, secondX, secondY); + if (winding1 == winding && winding2 == winding) { + otherPoly.length = 0; + otherIndices.length = 0; + polygon.push(x3); + polygon.push(y3); + polygonIndices.push(otherLastIndex); + prevPrevX = prevX; + prevPrevY = prevY; + prevX = x3; + prevY = y3; + ii = 0; + } + } + } + for (var i = convexPolygons.length - 1; i >= 0; i--) { + polygon = convexPolygons[i]; + if (polygon.length == 0) { + convexPolygons.splice(i, 1); + this.polygonPool.free(polygon); + polygonIndices = convexPolygonsIndices[i]; + convexPolygonsIndices.splice(i, 1); + this.polygonIndicesPool.free(polygonIndices); + } + } + return convexPolygons; + }; + Triangulator.isConcave = function (index, vertexCount, vertices, indices) { + var previous = indices[(vertexCount + index - 1) % vertexCount] << 1; + var current = indices[index] << 1; + var next = indices[(index + 1) % vertexCount] << 1; + return !this.positiveArea(vertices[previous], vertices[previous + 1], vertices[current], vertices[current + 1], vertices[next], vertices[next + 1]); + }; + Triangulator.positiveArea = function (p1x, p1y, p2x, p2y, p3x, p3y) { + return p1x * (p3y - p2y) + p2x * (p1y - p3y) + p3x * (p2y - p1y) >= 0; + }; + Triangulator.winding = function (p1x, p1y, p2x, p2y, p3x, p3y) { + var px = p2x - p1x, py = p2y - p1y; + return p3x * py - p3y * px + px * p1y - p1x * py >= 0 ? 1 : -1; + }; + return Triangulator; + }()); + spine.Triangulator = Triangulator; })(spine || (spine = {})); var spine; (function (spine) { @@ -5164,13 +5744,13 @@ var spine; this.a = 1; return this; }; - Color.WHITE = new Color(1, 1, 1, 1); - Color.RED = new Color(1, 0, 0, 1); - Color.GREEN = new Color(0, 1, 0, 1); - Color.BLUE = new Color(0, 0, 1, 1); - Color.MAGENTA = new Color(1, 0, 1, 1); return Color; }()); + Color.WHITE = new Color(1, 1, 1, 1); + Color.RED = new Color(1, 0, 0, 1); + Color.GREEN = new Color(0, 1, 0, 1); + Color.BLUE = new Color(0, 0, 1, 1); + Color.MAGENTA = new Color(1, 0, 1, 1); spine.Color = Color; var MathUtils = (function () { function MathUtils() { @@ -5198,15 +5778,61 @@ var spine; var y = Math.pow(Math.abs(x), 1 / 3); return x < 0 ? -y : y; }; - MathUtils.PI = 3.1415927; - MathUtils.PI2 = MathUtils.PI * 2; - MathUtils.radiansToDegrees = 180 / MathUtils.PI; - MathUtils.radDeg = MathUtils.radiansToDegrees; - MathUtils.degreesToRadians = MathUtils.PI / 180; - MathUtils.degRad = MathUtils.degreesToRadians; + MathUtils.randomTriangular = function (min, max) { + return MathUtils.randomTriangularWith(min, max, (min + max) * 0.5); + }; + MathUtils.randomTriangularWith = function (min, max, mode) { + var u = Math.random(); + var d = max - min; + if (u <= (mode - min) / d) + return min + Math.sqrt(u * d * (mode - min)); + return max - Math.sqrt((1 - u) * d * (max - mode)); + }; return MathUtils; }()); + MathUtils.PI = 3.1415927; + MathUtils.PI2 = MathUtils.PI * 2; + MathUtils.radiansToDegrees = 180 / MathUtils.PI; + MathUtils.radDeg = MathUtils.radiansToDegrees; + MathUtils.degreesToRadians = MathUtils.PI / 180; + MathUtils.degRad = MathUtils.degreesToRadians; spine.MathUtils = MathUtils; + var Interpolation = (function () { + function Interpolation() { + } + Interpolation.prototype.apply = function (start, end, a) { + return start + (end - start) * this.applyInternal(a); + }; + return Interpolation; + }()); + spine.Interpolation = Interpolation; + var Pow = (function (_super) { + __extends(Pow, _super); + function Pow(power) { + var _this = _super.call(this) || this; + _this.power = 2; + _this.power = power; + return _this; + } + Pow.prototype.applyInternal = function (a) { + if (a <= 0.5) + return Math.pow(a * 2, this.power) / 2; + return Math.pow((a - 1) * 2, this.power) / (this.power % 2 == 0 ? -2 : 2) + 1; + }; + return Pow; + }(Interpolation)); + spine.Pow = Pow; + var PowOut = (function (_super) { + __extends(PowOut, _super); + function PowOut(power) { + return _super.call(this, power) || this; + } + PowOut.prototype.applyInternal = function (a) { + return Math.pow(a - 1, this.power) * (this.power % 2 == 0 ? -1 : 1) + 1; + }; + return PowOut; + }(Pow)); + spine.PowOut = PowOut; var Utils = (function () { function Utils() { } @@ -5250,12 +5876,26 @@ var spine; return array; } }; + Utils.newShortArray = function (size) { + if (Utils.SUPPORTS_TYPED_ARRAYS) { + return new Int16Array(size); + } + else { + var array = new Array(size); + for (var i = 0; i < array.length; i++) + array[i] = 0; + return array; + } + }; Utils.toFloatArray = function (array) { return Utils.SUPPORTS_TYPED_ARRAYS ? new Float32Array(array) : array; }; - Utils.SUPPORTS_TYPED_ARRAYS = typeof (Float32Array) !== "undefined"; + Utils.toSinglePrecision = function (value) { + return Utils.SUPPORTS_TYPED_ARRAYS ? Math.fround(value) : value; + }; return Utils; }()); + Utils.SUPPORTS_TYPED_ARRAYS = typeof (Float32Array) !== "undefined"; spine.Utils = Utils; var DebugUtils = (function () { function DebugUtils() { @@ -5351,5 +5991,468 @@ var spine; return TimeKeeper; }()); spine.TimeKeeper = TimeKeeper; + var WindowedMean = (function () { + function WindowedMean(windowSize) { + if (windowSize === void 0) { windowSize = 32; } + this.addedValues = 0; + this.lastValue = 0; + this.mean = 0; + this.dirty = true; + this.values = new Array(windowSize); + } + WindowedMean.prototype.hasEnoughData = function () { + return this.addedValues >= this.values.length; + }; + WindowedMean.prototype.addValue = function (value) { + if (this.addedValues < this.values.length) + this.addedValues++; + this.values[this.lastValue++] = value; + if (this.lastValue > this.values.length - 1) + this.lastValue = 0; + this.dirty = true; + }; + WindowedMean.prototype.getMean = function () { + if (this.hasEnoughData()) { + if (this.dirty) { + var mean = 0; + for (var i = 0; i < this.values.length; i++) { + mean += this.values[i]; + } + this.mean = mean / this.values.length; + this.dirty = false; + } + return this.mean; + } + else { + return 0; + } + }; + return WindowedMean; + }()); + spine.WindowedMean = WindowedMean; +})(spine || (spine = {})); +var spine; +(function (spine) { + var Attachment = (function () { + function Attachment(name) { + if (name == null) + throw new Error("name cannot be null."); + this.name = name; + } + return Attachment; + }()); + spine.Attachment = Attachment; + var VertexAttachment = (function (_super) { + __extends(VertexAttachment, _super); + function VertexAttachment(name) { + var _this = _super.call(this, name) || this; + _this.id = (VertexAttachment.nextID++ & 65535) << 11; + _this.worldVerticesLength = 0; + return _this; + } + VertexAttachment.prototype.computeWorldVertices = function (slot, start, count, worldVertices, offset, stride) { + count = offset + (count >> 1) * stride; + var skeleton = slot.bone.skeleton; + var deformArray = slot.attachmentVertices; + var vertices = this.vertices; + var bones = this.bones; + if (bones == null) { + if (deformArray.length > 0) + vertices = deformArray; + var bone = slot.bone; + var x = bone.worldX; + var y = bone.worldY; + var a = bone.a, b = bone.b, c = bone.c, d = bone.d; + for (var v_1 = start, w = offset; w < count; v_1 += 2, w += stride) { + var vx = vertices[v_1], vy = vertices[v_1 + 1]; + worldVertices[w] = vx * a + vy * b + x; + worldVertices[w + 1] = vx * c + vy * d + y; + } + return; + } + var v = 0, skip = 0; + for (var i = 0; i < start; i += 2) { + var n = bones[v]; + v += n + 1; + skip += n; + } + var skeletonBones = skeleton.bones; + if (deformArray.length == 0) { + for (var w = offset, b = skip * 3; w < count; w += stride) { + var wx = 0, wy = 0; + var n = bones[v++]; + n += v; + for (; v < n; v++, b += 3) { + var bone = skeletonBones[bones[v]]; + var vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2]; + wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight; + wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight; + } + worldVertices[w] = wx; + worldVertices[w + 1] = wy; + } + } + else { + var deform = deformArray; + for (var w = offset, b = skip * 3, f = skip << 1; w < count; w += stride) { + var wx = 0, wy = 0; + var n = bones[v++]; + n += v; + for (; v < n; v++, b += 3, f += 2) { + var bone = skeletonBones[bones[v]]; + var vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2]; + wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight; + wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight; + } + worldVertices[w] = wx; + worldVertices[w + 1] = wy; + } + } + }; + VertexAttachment.prototype.applyDeform = function (sourceAttachment) { + return this == sourceAttachment; + }; + return VertexAttachment; + }(Attachment)); + VertexAttachment.nextID = 0; + spine.VertexAttachment = VertexAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + var AttachmentType; + (function (AttachmentType) { + AttachmentType[AttachmentType["Region"] = 0] = "Region"; + AttachmentType[AttachmentType["BoundingBox"] = 1] = "BoundingBox"; + AttachmentType[AttachmentType["Mesh"] = 2] = "Mesh"; + AttachmentType[AttachmentType["LinkedMesh"] = 3] = "LinkedMesh"; + AttachmentType[AttachmentType["Path"] = 4] = "Path"; + AttachmentType[AttachmentType["Point"] = 5] = "Point"; + })(AttachmentType = spine.AttachmentType || (spine.AttachmentType = {})); +})(spine || (spine = {})); +var spine; +(function (spine) { + var BoundingBoxAttachment = (function (_super) { + __extends(BoundingBoxAttachment, _super); + function BoundingBoxAttachment(name) { + var _this = _super.call(this, name) || this; + _this.color = new spine.Color(1, 1, 1, 1); + return _this; + } + return BoundingBoxAttachment; + }(spine.VertexAttachment)); + spine.BoundingBoxAttachment = BoundingBoxAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + var ClippingAttachment = (function (_super) { + __extends(ClippingAttachment, _super); + function ClippingAttachment(name) { + var _this = _super.call(this, name) || this; + _this.color = new spine.Color(0.2275, 0.2275, 0.8078, 1); + return _this; + } + return ClippingAttachment; + }(spine.VertexAttachment)); + spine.ClippingAttachment = ClippingAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + var MeshAttachment = (function (_super) { + __extends(MeshAttachment, _super); + function MeshAttachment(name) { + var _this = _super.call(this, name) || this; + _this.color = new spine.Color(1, 1, 1, 1); + _this.inheritDeform = false; + _this.tempColor = new spine.Color(0, 0, 0, 0); + return _this; + } + MeshAttachment.prototype.updateUVs = function () { + var u = 0, v = 0, width = 0, height = 0; + if (this.region == null) { + u = v = 0; + width = height = 1; + } + else { + u = this.region.u; + v = this.region.v; + width = this.region.u2 - u; + height = this.region.v2 - v; + } + var regionUVs = this.regionUVs; + if (this.uvs == null || this.uvs.length != regionUVs.length) + this.uvs = spine.Utils.newFloatArray(regionUVs.length); + var uvs = this.uvs; + if (this.region.rotate) { + for (var i = 0, n = uvs.length; i < n; i += 2) { + uvs[i] = u + regionUVs[i + 1] * width; + uvs[i + 1] = v + height - regionUVs[i] * height; + } + } + else { + for (var i = 0, n = uvs.length; i < n; i += 2) { + uvs[i] = u + regionUVs[i] * width; + uvs[i + 1] = v + regionUVs[i + 1] * height; + } + } + }; + MeshAttachment.prototype.applyDeform = function (sourceAttachment) { + return this == sourceAttachment || (this.inheritDeform && this.parentMesh == sourceAttachment); + }; + MeshAttachment.prototype.getParentMesh = function () { + return this.parentMesh; + }; + MeshAttachment.prototype.setParentMesh = function (parentMesh) { + this.parentMesh = parentMesh; + if (parentMesh != null) { + this.bones = parentMesh.bones; + this.vertices = parentMesh.vertices; + this.worldVerticesLength = parentMesh.worldVerticesLength; + this.regionUVs = parentMesh.regionUVs; + this.triangles = parentMesh.triangles; + this.hullLength = parentMesh.hullLength; + this.worldVerticesLength = parentMesh.worldVerticesLength; + } + }; + return MeshAttachment; + }(spine.VertexAttachment)); + spine.MeshAttachment = MeshAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + var PathAttachment = (function (_super) { + __extends(PathAttachment, _super); + function PathAttachment(name) { + var _this = _super.call(this, name) || this; + _this.closed = false; + _this.constantSpeed = false; + _this.color = new spine.Color(1, 1, 1, 1); + return _this; + } + return PathAttachment; + }(spine.VertexAttachment)); + spine.PathAttachment = PathAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + var PointAttachment = (function (_super) { + __extends(PointAttachment, _super); + function PointAttachment(name) { + var _this = _super.call(this, name) || this; + _this.color = new spine.Color(0.38, 0.94, 0, 1); + return _this; + } + PointAttachment.prototype.computeWorldPosition = function (bone, point) { + point.x = this.x * bone.a + this.y * bone.b + bone.worldX; + point.y = this.x * bone.c + this.y * bone.d + bone.worldY; + return point; + }; + PointAttachment.prototype.computeWorldRotation = function (bone) { + var cos = spine.MathUtils.cosDeg(this.rotation), sin = spine.MathUtils.sinDeg(this.rotation); + var x = cos * bone.a + sin * bone.b; + var y = cos * bone.c + sin * bone.d; + return Math.atan2(y, x) * spine.MathUtils.radDeg; + }; + return PointAttachment; + }(spine.VertexAttachment)); + spine.PointAttachment = PointAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + var RegionAttachment = (function (_super) { + __extends(RegionAttachment, _super); + function RegionAttachment(name) { + var _this = _super.call(this, name) || this; + _this.x = 0; + _this.y = 0; + _this.scaleX = 1; + _this.scaleY = 1; + _this.rotation = 0; + _this.width = 0; + _this.height = 0; + _this.color = new spine.Color(1, 1, 1, 1); + _this.offset = spine.Utils.newFloatArray(8); + _this.uvs = spine.Utils.newFloatArray(8); + _this.tempColor = new spine.Color(1, 1, 1, 1); + return _this; + } + RegionAttachment.prototype.updateOffset = function () { + var regionScaleX = this.width / this.region.originalWidth * this.scaleX; + var regionScaleY = this.height / this.region.originalHeight * this.scaleY; + var localX = -this.width / 2 * this.scaleX + this.region.offsetX * regionScaleX; + var localY = -this.height / 2 * this.scaleY + this.region.offsetY * regionScaleY; + var localX2 = localX + this.region.width * regionScaleX; + var localY2 = localY + this.region.height * regionScaleY; + var radians = this.rotation * Math.PI / 180; + var cos = Math.cos(radians); + var sin = Math.sin(radians); + var localXCos = localX * cos + this.x; + var localXSin = localX * sin; + var localYCos = localY * cos + this.y; + var localYSin = localY * sin; + var localX2Cos = localX2 * cos + this.x; + var localX2Sin = localX2 * sin; + var localY2Cos = localY2 * cos + this.y; + var localY2Sin = localY2 * sin; + var offset = this.offset; + offset[RegionAttachment.OX1] = localXCos - localYSin; + offset[RegionAttachment.OY1] = localYCos + localXSin; + offset[RegionAttachment.OX2] = localXCos - localY2Sin; + offset[RegionAttachment.OY2] = localY2Cos + localXSin; + offset[RegionAttachment.OX3] = localX2Cos - localY2Sin; + offset[RegionAttachment.OY3] = localY2Cos + localX2Sin; + offset[RegionAttachment.OX4] = localX2Cos - localYSin; + offset[RegionAttachment.OY4] = localYCos + localX2Sin; + }; + RegionAttachment.prototype.setRegion = function (region) { + this.region = region; + var uvs = this.uvs; + if (region.rotate) { + uvs[2] = region.u; + uvs[3] = region.v2; + uvs[4] = region.u; + uvs[5] = region.v; + uvs[6] = region.u2; + uvs[7] = region.v; + uvs[0] = region.u2; + uvs[1] = region.v2; + } + else { + uvs[0] = region.u; + uvs[1] = region.v2; + uvs[2] = region.u; + uvs[3] = region.v; + uvs[4] = region.u2; + uvs[5] = region.v; + uvs[6] = region.u2; + uvs[7] = region.v2; + } + }; + RegionAttachment.prototype.computeWorldVertices = function (bone, worldVertices, offset, stride) { + var vertexOffset = this.offset; + var x = bone.worldX, y = bone.worldY; + var a = bone.a, b = bone.b, c = bone.c, d = bone.d; + var offsetX = 0, offsetY = 0; + offsetX = vertexOffset[RegionAttachment.OX1]; + offsetY = vertexOffset[RegionAttachment.OY1]; + worldVertices[offset] = offsetX * a + offsetY * b + x; + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[RegionAttachment.OX2]; + offsetY = vertexOffset[RegionAttachment.OY2]; + worldVertices[offset] = offsetX * a + offsetY * b + x; + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[RegionAttachment.OX3]; + offsetY = vertexOffset[RegionAttachment.OY3]; + worldVertices[offset] = offsetX * a + offsetY * b + x; + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[RegionAttachment.OX4]; + offsetY = vertexOffset[RegionAttachment.OY4]; + worldVertices[offset] = offsetX * a + offsetY * b + x; + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + }; + return RegionAttachment; + }(spine.Attachment)); + RegionAttachment.OX1 = 0; + RegionAttachment.OY1 = 1; + RegionAttachment.OX2 = 2; + RegionAttachment.OY2 = 3; + RegionAttachment.OX3 = 4; + RegionAttachment.OY3 = 5; + RegionAttachment.OX4 = 6; + RegionAttachment.OY4 = 7; + RegionAttachment.X1 = 0; + RegionAttachment.Y1 = 1; + RegionAttachment.C1R = 2; + RegionAttachment.C1G = 3; + RegionAttachment.C1B = 4; + RegionAttachment.C1A = 5; + RegionAttachment.U1 = 6; + RegionAttachment.V1 = 7; + RegionAttachment.X2 = 8; + RegionAttachment.Y2 = 9; + RegionAttachment.C2R = 10; + RegionAttachment.C2G = 11; + RegionAttachment.C2B = 12; + RegionAttachment.C2A = 13; + RegionAttachment.U2 = 14; + RegionAttachment.V2 = 15; + RegionAttachment.X3 = 16; + RegionAttachment.Y3 = 17; + RegionAttachment.C3R = 18; + RegionAttachment.C3G = 19; + RegionAttachment.C3B = 20; + RegionAttachment.C3A = 21; + RegionAttachment.U3 = 22; + RegionAttachment.V3 = 23; + RegionAttachment.X4 = 24; + RegionAttachment.Y4 = 25; + RegionAttachment.C4R = 26; + RegionAttachment.C4G = 27; + RegionAttachment.C4B = 28; + RegionAttachment.C4A = 29; + RegionAttachment.U4 = 30; + RegionAttachment.V4 = 31; + spine.RegionAttachment = RegionAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + var JitterEffect = (function () { + function JitterEffect(jitterX, jitterY) { + this.jitterX = 0; + this.jitterY = 0; + this.jitterX = jitterX; + this.jitterY = jitterY; + } + JitterEffect.prototype.begin = function (skeleton) { + }; + JitterEffect.prototype.transform = function (position, uv, light, dark) { + position.x += spine.MathUtils.randomTriangular(-this.jitterX, this.jitterY); + position.y += spine.MathUtils.randomTriangular(-this.jitterX, this.jitterY); + }; + JitterEffect.prototype.end = function () { + }; + return JitterEffect; + }()); + spine.JitterEffect = JitterEffect; +})(spine || (spine = {})); +var spine; +(function (spine) { + var SwirlEffect = (function () { + function SwirlEffect(radius) { + this.centerX = 0; + this.centerY = 0; + this.radius = 0; + this.angle = 0; + this.worldX = 0; + this.worldY = 0; + this.radius = radius; + } + SwirlEffect.prototype.begin = function (skeleton) { + this.worldX = skeleton.x + this.centerX; + this.worldY = skeleton.y + this.centerY; + }; + SwirlEffect.prototype.transform = function (position, uv, light, dark) { + var radAngle = this.angle * spine.MathUtils.degreesToRadians; + var x = position.x - this.worldX; + var y = position.y - this.worldY; + var dist = Math.sqrt(x * x + y * y); + if (dist < this.radius) { + var theta = SwirlEffect.interpolation.apply(0, radAngle, (this.radius - dist) / this.radius); + var cos = Math.cos(theta); + var sin = Math.sin(theta); + position.x = cos * x - sin * y + this.worldX; + position.y = sin * x + cos * y + this.worldY; + } + }; + SwirlEffect.prototype.end = function () { + }; + return SwirlEffect; + }()); + SwirlEffect.interpolation = new spine.PowOut(2); + spine.SwirlEffect = SwirlEffect; })(spine || (spine = {})); -//# sourceMappingURL=spine-core.js.map \ No newline at end of file + +var sp = sp || {}; +sp.spine = spine; diff --git a/moduleConfig.json b/moduleConfig.json index 1b147f43c6..55a9e81c60 100644 --- a/moduleConfig.json +++ b/moduleConfig.json @@ -228,6 +228,7 @@ "cocos2d/shaders/CCShaders.js", "cocos2d/shaders/CCShaderCache.js", "cocos2d/shaders/CCGLProgram.js", + "cocos2d/shaders/CCGLProgramState.js", "cocos2d/shaders/CCGLStateCache.js" ], "shape-nodes" : [