diff --git a/CCBoot.js b/CCBoot.js index 967fdfa891..7746de2288 100644 --- a/CCBoot.js +++ b/CCBoot.js @@ -23,12 +23,45 @@ THE SOFTWARE. ****************************************************************************/ + + /** * The main namespace of Cocos2d-JS, all engine core classes, functions, properties and constants are defined in this namespace * @namespace * @name cc */ var cc = cc || {}; + +cc.create3DContext = function (canvas, opt_attribs) { + var names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"]; + var context = null; + for (var ii = 0; ii < names.length; ++ii) { + try { + context = canvas.getContext(names[ii], opt_attribs); + } catch (e) { + } + if (context) { + break; + } + } + return context; +}; + +/* +(function () { + var canvas = document.getElementById("gameCanvas"); + if (canvas) { + var ctx = cc.create3DContext(canvas); + + if(!ctx) + { + throw new Error("LOL!"); + } + } +} +)(); +*/ + cc._tmp = cc._tmp || {}; cc._LogInfos = {}; @@ -1184,20 +1217,7 @@ cc.formatStr = function(){ var _tmpCanvas1 = document.createElement("canvas"), _tmpCanvas2 = document.createElement("canvas"); -cc.create3DContext = function (canvas, opt_attribs) { - var names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"]; - var context = null; - for (var ii = 0; ii < names.length; ++ii) { - try { - context = canvas.getContext(names[ii], opt_attribs); - } catch (e) { - } - if (context) { - break; - } - } - return context; -}; + var _initSys = function () { /** @@ -2210,6 +2230,11 @@ cc.game = /** @lends cc.game# */{ config = self.config, CONFIG_KEY = self.CONFIG_KEY; + if(window["gli"]) //if webinspector is installed, we have to hook iterator + { + gli.setupContext(); + } + this._loadConfig(); // Already prepared @@ -2497,6 +2522,9 @@ cc.game = /** @lends cc.game# */{ cc.shaderCache._init(); cc._drawingUtil = new cc.DrawingPrimitiveWebGL(this._renderContext); cc.textureCache._initializingRenderer(); + cc.glExt = {}; + cc.glExt.instanced_arrays = gl.getExtension("ANGLE_instanced_arrays"); + cc.glExt.element_uint = gl.getExtension("OES_element_index_uint"); } else { cc.renderer = cc.rendererCanvas; this._renderContext = cc._renderContext = new cc.CanvasContextWrapper(localCanvas.getContext("2d")); diff --git a/cocos2d/clipping-nodes/CCClippingNode.js b/cocos2d/clipping-nodes/CCClippingNode.js index a9f301a658..5dea8bcf4c 100644 --- a/cocos2d/clipping-nodes/CCClippingNode.js +++ b/cocos2d/clipping-nodes/CCClippingNode.js @@ -195,9 +195,6 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{ }, _createRenderCmd: function(){ - if(cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new cc.ClippingNode.CanvasRenderCmd(this); - else return new cc.ClippingNode.WebGLRenderCmd(this); } }); diff --git a/cocos2d/clipping-nodes/CCClippingNodeCanvasRenderCmd.js b/cocos2d/clipping-nodes/CCClippingNodeCanvasRenderCmd.js index 5c60928ab0..e69de29bb2 100644 --- a/cocos2d/clipping-nodes/CCClippingNodeCanvasRenderCmd.js +++ b/cocos2d/clipping-nodes/CCClippingNodeCanvasRenderCmd.js @@ -1,215 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -//-------------------------- ClippingNode's canvas render cmd -------------------------------- -(function(){ - cc.ClippingNode.CanvasRenderCmd = function(renderable){ - cc.Node.CanvasRenderCmd.call(this, renderable); - this._needDraw = false; - - this._godhelpme = false; - this._clipElemType = false; - - this._rendererSaveCmd = new cc.CustomRenderCmd(this, this._saveCmdCallback); - this._rendererClipCmd = new cc.CustomRenderCmd(this, this._clipCmdCallback); - this._rendererRestoreCmd = new cc.CustomRenderCmd(this, this._restoreCmdCallback); - }; - var proto = cc.ClippingNode.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype); - proto.constructor = cc.ClippingNode.CanvasRenderCmd; - - proto.initStencilBits = function(){}; - - proto.setStencil = function(stencil){ - if(stencil == null) - return; - - this._node._stencil = stencil; - - // For shape stencil, rewrite the draw of stencil ,only init the clip path and draw nothing. - //else - if (stencil instanceof cc.DrawNode) { - if(stencil._buffer){ - for(var i=0; i 0; j--) - context.lineTo(vertices[j].x * scaleX, -vertices[j].y * scaleY); - } - }; - }else{ - stencil._parent = this._node; - } - }; - - proto._saveCmdCallback = function(ctx, scaleX, scaleY) { - var wrapper = ctx || cc._renderContext, context = wrapper.getContext(); - - if (this._clipElemType) { - var locCache = cc.ClippingNode.CanvasRenderCmd._getSharedCache(); - var canvas = context.canvas; - locCache.width = canvas.width; - locCache.height = canvas.height; //note: on some browser, it can't clear the canvas, e.g. baidu - var locCacheCtx = locCache.getContext("2d"); - locCacheCtx.drawImage(canvas, 0, 0); //save the result to shareCache canvas - } else { - wrapper.save(); - context.beginPath(); //save for clip - //Because drawNode's content size is zero - wrapper.setTransform(this._worldTransform, scaleX, scaleY); - - if (this._node.inverted) { - context.rect(0, 0, context.canvas.width, -context.canvas.height); - context.clip(); - } - } - }; - - proto._setStencilCompositionOperation = function(stencil){ - if(!stencil) - return; - var node = this._node; - if(stencil._renderCmd && stencil._renderCmd._blendFuncStr) //it is a hack way. - stencil._renderCmd._blendFuncStr = (node.inverted ? "destination-out" : "destination-in"); - - if(!stencil._children) - return; - var children = stencil._children; - for(var i = 0, len = children.length; i < len; i++){ - this._setStencilCompositionOperation(children[i]); - } - }; - - proto._clipCmdCallback = function(ctx) { - var node = this._node; - var wrapper = ctx || cc._renderContext, context = wrapper.getContext(); - - if (this._clipElemType) { - //hack - this._setStencilCompositionOperation(node._stencil); - } else { - context.clip(); - } - }; - - proto._restoreCmdCallback = function (ctx) { - var locCache = cc.ClippingNode.CanvasRenderCmd._getSharedCache(); - var wrapper = ctx || cc._renderContext, context = wrapper.getContext(); - if (this._clipElemType) { - // Redraw the cached canvas, so that the clipped area shows the background etc. - context.save(); - context.setTransform(1, 0, 0, 1, 0, 0); - context.globalCompositeOperation = "destination-over"; - context.drawImage(locCache, 0, 0); - context.restore(); - this._dirtyFlag = 0; - } else { - wrapper.restore(); //use for restore clip operation - } - }; - - proto.transform = function(parentCmd, recursive){ - cc.Node.CanvasRenderCmd.prototype.transform.call(this, parentCmd, recursive); - var node = this._node; - if(node._stencil && node._stencil._renderCmd) - node._stencil._renderCmd.transform(this, recursive); - }; - - proto._cangodhelpme = function (godhelpme) { - if (godhelpme === true || godhelpme === false) - cc.ClippingNode.CanvasRenderCmd.prototype._godhelpme = godhelpme; - return cc.ClippingNode.CanvasRenderCmd.prototype._godhelpme; - }; - - proto.visit = function(parentCmd){ - var node = this._node; - // quick return if not visible - if (!node._visible) - return; - - parentCmd = parentCmd || this.getParentRenderCmd(); - if( parentCmd) - this._curLevel = parentCmd._curLevel + 1; - var transformRenderCmd = this; - - // Composition mode, costy but support texture stencil - this._clipElemType = !(!this._cangodhelpme() && node._stencil instanceof cc.DrawNode); - if (!node._stencil || !node._stencil.visible) { - if (this.inverted) - cc.Node.CanvasRenderCmd.prototype.visit.call(this, parentCmd); // draw everything - return; - } - - this._syncStatus(parentCmd); - cc.renderer.pushRenderCommand(this._rendererSaveCmd); - if(this._clipElemType){ - // Draw everything first using node visit function - cc.Node.CanvasRenderCmd.prototype.visit.call(this, parentCmd); - }else{ - node._stencil.visit(this); - } - cc.renderer.pushRenderCommand(this._rendererClipCmd); - - if(this._clipElemType){ - node._stencil.visit(transformRenderCmd); - }else{ - var i, children = node._children; - // Clip mode doesn't support recursive stencil, so once we used a clip stencil, - // so if it has ClippingNode as a child, the child must uses composition stencil. - this._cangodhelpme(true); - var len = children.length; - if (len > 0) { - node.sortAllChildren(); - for (i = 0; i < len; i++) - children[i]._renderCmd.visit(this); - } - this._cangodhelpme(false); - } - - cc.renderer.pushRenderCommand(this._rendererRestoreCmd); - this._dirtyFlag = 0; - }; - - cc.ClippingNode.CanvasRenderCmd._sharedCache = null; - cc.ClippingNode.CanvasRenderCmd._getSharedCache = function () { - return (cc.ClippingNode.CanvasRenderCmd._sharedCache) || (cc.ClippingNode.CanvasRenderCmd._sharedCache = document.createElement("canvas")); - }; -})(); \ No newline at end of file diff --git a/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js b/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js index 0e199ff3b7..d61a4719a0 100644 --- a/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js +++ b/cocos2d/clipping-nodes/CCClippingNodeWebGLRenderCmd.js @@ -173,14 +173,11 @@ var gl = ctx || cc._renderContext, node = this._node; cc.ClippingNode.WebGLRenderCmd._layer++; - // mask of the current layer (ie: for layer 3: 00000100) + var mask_layer = 0x1 << cc.ClippingNode.WebGLRenderCmd._layer; - // mask of all layers less than the current (ie: for layer 3: 00000011) var mask_layer_l = mask_layer - 1; - // mask of all layers less than or equal to the current (ie: for layer 3: 00000111) - //var mask_layer_le = mask_layer | mask_layer_l; this._mask_layer_le = mask_layer | mask_layer_l; - // manually save the stencil state + this._currentStencilEnabled = gl.isEnabled(gl.STENCIL_TEST); this._currentStencilWriteMask = gl.getParameter(gl.STENCIL_WRITEMASK); this._currentStencilFunc = gl.getParameter(gl.STENCIL_FUNC); diff --git a/cocos2d/core/CCDirector.js b/cocos2d/core/CCDirector.js index 74b10fd449..c0c67b9213 100644 --- a/cocos2d/core/CCDirector.js +++ b/cocos2d/core/CCDirector.js @@ -202,7 +202,60 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{ * @return {cc.Point} */ convertToUI: null, - + + traverseAndSetZ: function(node) + { + var minZ = Number.MAX_VALUE; + var maxZ = -Number.MAX_VALUE; + + var children = node.children; + + var len = children.length; + + for(var i=0;iDefines the oder in which the nodes are renderer.
- * Nodes that have a Global Z Order lower, are renderer first.
- *
- * In case two or more nodes have the same Global Z Order, the oder is not guaranteed.
- * The only exception if the Nodes have a Global Z Order == 0. In that case, the Scene Graph order is used.
- *
- * By default, all nodes have a Global Z Order = 0. That means that by default, the Scene Graph order is used to render the nodes.
- *
- * Global Z Order is useful when you need to render nodes in an order different than the Scene Graph order.
- *
- * Limitations: Global Z Order can't be used used by Nodes that have SpriteBatchNode as one of their ancestors.
- * And if ClippingNode is one of the ancestors, then "global Z order" will be relative to the ClippingNode.

- * @function - * @param {Number} globalZOrder - */ - setGlobalZOrder: function (globalZOrder) { - if (this._globalZOrder !== globalZOrder) { - this._globalZOrder = globalZOrder; - cc.eventManager._setDirtyForNode(this); - } - }, - - /** - * Return the Node's Global Z Order. - * @function - * @returns {number} The node's global Z order - */ - getGlobalZOrder: function () { - return this._globalZOrder; - }, - /** * Returns WebGL Z vertex of this node. * @function @@ -661,29 +623,6 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{ locPosition.x = newPosOrxValue; locPosition.y = yValue; } - this._usingNormalizedPosition = false; - this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty); - }, - - /** - *

- * Sets the position (x,y) using values between 0 and 1.
- * The positions in pixels is calculated like the following:
- * _position = _normalizedPosition * parent.getContentSize() - *

- * @param {cc.Point|Number} posOrX - * @param {Number} [y] - */ - setNormalizedPosition: function(posOrX, y){ - var locPosition = this._normalizedPosition; - if (y === undefined) { - locPosition.x = posOrX.x; - locPosition.y = posOrX.y; - } else { - locPosition.x = posOrX; - locPosition.y = y; - } - this._normalizedPositionDirty = this._usingNormalizedPosition = true; this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty); }, @@ -696,14 +635,6 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{ return cc.p(this._position); }, - /** - * returns the normalized position - * @returns {cc.Point} - */ - getNormalizedPosition: function(){ - return cc.p(this._normalizedPosition); - }, - /** *

Returns the x axis position of the node in cocos2d coordinates.

* @function @@ -2438,9 +2369,6 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{ }, _createRenderCmd: function(){ - if(cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new cc.Node.CanvasRenderCmd(this); - else return new cc.Node.WebGLRenderCmd(this); }, diff --git a/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js b/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js index bc802ed5f0..4d72dacbc0 100644 --- a/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js +++ b/cocos2d/core/base-nodes/CCNodeCanvasRenderCmd.js @@ -238,13 +238,6 @@ cc.Node.RenderCmd.prototype = { getNodeToParentTransform: function () { var node = this._node; - if (node._usingNormalizedPosition && node._parent) { //TODO need refactor - var conSize = node._parent._contentSize; - node._position.x = node._normalizedPosition.x * conSize.width; - node._position.y = node._normalizedPosition.y * conSize.height; - node._normalizedPositionDirty = false; - this._dirtyFlag = this._dirtyFlag | cc.Node._dirtyFlags.transformDirty; - } if (this._dirtyFlag & cc.Node._dirtyFlags.transformDirty) { var t = this._transform;// quick reference @@ -321,7 +314,29 @@ cc.Node.RenderCmd.prototype = { } return this._transform; }, + getRenderZ: function(parentCmd) + { + var node = this._node; + if(node.__z) + { + return node.__z; + } + else if(parentCmd && parentCmd._node.__z) + { + return parentCmd._node.__z; + } + else + { + return 0; + } + }, + setRenderZ: function(parentCmd, matrix) + { + var node = this._node; + var parentCmd = parentCmd || this.getParentRenderCmd(); + matrix.mat[14] = this.getRenderZ(parentCmd); + }, _syncStatus: function (parentCmd) { // In the visit logic does not restore the _dirtyFlag // Because child elements need parent's _dirtyFlag to change himself diff --git a/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js b/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js index 88cab78044..cad99cb0e4 100644 --- a/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js +++ b/cocos2d/core/base-nodes/CCNodeWebGLRenderCmd.js @@ -80,36 +80,12 @@ t4x4Mat[5] = trans.d; t4x4Mat[13] = trans.ty; - // Update Z vertex manually - t4x4Mat[14] = node._vertexZ; - //optimize performance for Javascript cc.kmMat4Multiply(stackMatrix, parentMatrix, t4x4); + + this.setRenderZ(parentCmd, stackMatrix); - // XXX: Expensive calls. Camera should be integrated into the cached affine matrix - if (node._camera !== null && !(node.grid !== null && node.grid.isActive())) { - var apx = this._anchorPointInPoints.x, apy = this._anchorPointInPoints.y; - var translate = (apx !== 0.0 || apy !== 0.0); - if (translate){ - if(!cc.SPRITEBATCHNODE_RENDER_SUBPIXEL) { - apx = 0 | apx; - apy = 0 | apy; - } - //cc.kmGLTranslatef(apx, apy, 0); - var translation = cc.math.Matrix4.createByTranslation(apx, apy, 0, t4x4); //t4x4 as a temp matrix - stackMatrix.multiply(translation); - - node._camera._locateForRenderer(stackMatrix); - - //cc.kmGLTranslatef(-apx, -apy, 0); optimize at here : kmGLTranslatef - translation = cc.math.Matrix4.createByTranslation(-apx, -apy, 0, translation); - stackMatrix.multiply(translation); - t4x4.identity(); //reset t4x4; - } else { - node._camera._locateForRenderer(stackMatrix); - } - } - if(!recursive || !node._children || node._children.length === 0) + if(!recursive || !node._children) return; var i, len, locChildren = node._children; for(i = 0, len = locChildren.length; i< len; i++){ diff --git a/cocos2d/core/event-manager/CCEventManager.js b/cocos2d/core/event-manager/CCEventManager.js index 2bc5e1f620..4f77de9668 100644 --- a/cocos2d/core/event-manager/CCEventManager.js +++ b/cocos2d/core/event-manager/CCEventManager.js @@ -114,7 +114,6 @@ cc.eventManager = /** @lends cc.eventManager# */{ _priorityDirtyFlagMap: {}, _nodeListenersMap: {}, _nodePriorityMap: {}, - _globalZOrderNodeMap: {}, _toAddedListeners: [], _dirtyNodes: [], _inDispatch: 0, @@ -587,7 +586,7 @@ cc.eventManager = /** @lends cc.eventManager# */{ _visitTarget: function (node, isRootNode) { var children = node.getChildren(), i = 0; - var childrenCount = children.length, locGlobalZOrderNodeMap = this._globalZOrderNodeMap, locNodeListenersMap = this._nodeListenersMap; + var childrenCount = children.length, locNodeListenersMap = this._nodeListenersMap; if (childrenCount > 0) { var child; @@ -600,39 +599,11 @@ cc.eventManager = /** @lends cc.eventManager# */{ break; } - if (locNodeListenersMap[node.__instanceId] != null) { - if (!locGlobalZOrderNodeMap[node.getGlobalZOrder()]) - locGlobalZOrderNodeMap[node.getGlobalZOrder()] = []; - locGlobalZOrderNodeMap[node.getGlobalZOrder()].push(node.__instanceId); - } - for (; i < childrenCount; i++) { child = children[i]; if (child) this._visitTarget(child, false); } - } else { - if (locNodeListenersMap[node.__instanceId] != null) { - if (!locGlobalZOrderNodeMap[node.getGlobalZOrder()]) - locGlobalZOrderNodeMap[node.getGlobalZOrder()] = []; - locGlobalZOrderNodeMap[node.getGlobalZOrder()].push(node.__instanceId); - } - } - - if (isRootNode) { - var globalZOrders = []; - for (var selKey in locGlobalZOrderNodeMap) - globalZOrders.push(selKey); - - globalZOrders.sort(this._sortNumberAsc); - - var zOrdersLen = globalZOrders.length, selZOrders, j, locNodePriorityMap = this._nodePriorityMap; - for (i = 0; i < zOrdersLen; i++) { - selZOrders = locGlobalZOrderNodeMap[globalZOrders[i]]; - for (j = 0; j < selZOrders.length; j++) - locNodePriorityMap[selZOrders[j]] = ++this._nodePriorityIndex; - } - this._globalZOrderNodeMap = {}; } }, diff --git a/cocos2d/core/labelttf/CCLabelTTF.js b/cocos2d/core/labelttf/CCLabelTTF.js index 4e1756e9ad..ee9ef951c7 100644 --- a/cocos2d/core/labelttf/CCLabelTTF.js +++ b/cocos2d/core/labelttf/CCLabelTTF.js @@ -752,8 +752,6 @@ cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{ return new cc.LabelTTF.WebGLRenderCmd(this); else if (this._onCacheCanvasMode) return new cc.LabelTTF.CacheCanvasRenderCmd(this); - else - return new cc.LabelTTF.CanvasRenderCmd(this); }, //For web only diff --git a/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js b/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js index 27023ed440..08245e0ceb 100644 --- a/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js +++ b/cocos2d/core/labelttf/CCLabelTTFCanvasRenderCmd.js @@ -412,97 +412,4 @@ cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/; return this._labelContext.measureText(text).width; }; -})(); - -(function(){ - cc.LabelTTF.CacheCanvasRenderCmd = function (renderable) { - cc.Sprite.CanvasRenderCmd.call(this, renderable); - cc.LabelTTF.CacheRenderCmd.call(this); - }; - - var proto = cc.LabelTTF.CacheCanvasRenderCmd.prototype = Object.create(cc.Sprite.CanvasRenderCmd.prototype); - cc.inject(cc.LabelTTF.CacheRenderCmd.prototype, proto); - proto.constructor = cc.LabelTTF.CacheCanvasRenderCmd; -})(); - -(function(){ - cc.LabelTTF.CanvasRenderCmd = function (renderable) { - cc.Sprite.CanvasRenderCmd.call(this, renderable); - cc.LabelTTF.RenderCmd.call(this); - }; - - cc.LabelTTF.CanvasRenderCmd.prototype = Object.create(cc.Sprite.CanvasRenderCmd.prototype); - cc.inject(cc.LabelTTF.RenderCmd.prototype, cc.LabelTTF.CanvasRenderCmd.prototype); - - var proto = cc.LabelTTF.CanvasRenderCmd.prototype; - proto.constructor = cc.LabelTTF.CanvasRenderCmd; - - proto._measureConfig = function () {}; - - proto._measure = function (text) { - var context = cc._renderContext.getContext(); - context.font = this._fontStyleStr; - return context.measureText(text).width; - }; - - proto._updateTexture = function () { - this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.textDirty ^ this._dirtyFlag; - var node = this._node; - var locContentSize = node._contentSize; - this._updateTTF(); - var width = locContentSize.width, height = locContentSize.height; - if (node._string.length === 0) { - node.setTextureRect(cc.rect(0, 0, 1, locContentSize.height)); - return true; - } - this._saveStatus(); - node.setTextureRect(cc.rect(0, 0, width, height)); - return true; - }; - - proto.rendering = function(ctx) { - var scaleX = cc.view.getScaleX(), - scaleY = cc.view.getScaleY(); - var wrapper = ctx || cc._renderContext, context = wrapper.getContext(); - if (!context) - return; - var node = this._node; - wrapper.computeRealOffsetY(); - if(this._status.length <= 0) - return; - var locIndex = (this._renderingIndex >= this._status.length)? this._renderingIndex-this._status.length:this._renderingIndex; - var status = this._status[locIndex]; - this._renderingIndex = locIndex+1; - - var locHeight = node._rect.height, - locX = node._offsetPosition.x, - locY = -node._offsetPosition.y - locHeight; - - var alpha = (this._displayedOpacity / 255); - - wrapper.setTransform(this._worldTransform, scaleX, scaleY); - wrapper.setCompositeOperation(this._blendFuncStr); - wrapper.setGlobalAlpha(alpha); - - wrapper.save(); - - if (node._flippedX) { - locX = -locX - node._rect.width; - context.scale(-1, 1); - } - if (node._flippedY) { - locY = node._offsetPosition.y; - context.scale(1, -1); - } - - var xOffset = status.xOffset + status.contextTransform.x + locX * scaleX; - var yOffsetArray = []; - - var locStrLen = this._strings.length; - for (var i = 0; i < locStrLen; i++) - yOffsetArray.push(status.OffsetYArray[i] + status.contextTransform.y + locY * scaleY); - - this.drawLabels(context, xOffset, yOffsetArray); - wrapper.restore(); - }; })(); \ No newline at end of file diff --git a/cocos2d/core/layers/CCLayer.js b/cocos2d/core/layers/CCLayer.js index e9457535a6..6dfbc08c7a 100644 --- a/cocos2d/core/layers/CCLayer.js +++ b/cocos2d/core/layers/CCLayer.js @@ -92,9 +92,6 @@ cc.Layer = cc.Node.extend(/** @lends cc.Layer# */{ }, _createRenderCmd: function(){ - if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new cc.Layer.CanvasRenderCmd(this); - else return new cc.Layer.WebGLRenderCmd(this); } }); @@ -255,9 +252,6 @@ cc.LayerColor = cc.Layer.extend(/** @lends cc.LayerColor# */{ }, _createRenderCmd: function(){ - if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new cc.LayerColor.CanvasRenderCmd(this); - else return new cc.LayerColor.WebGLRenderCmd(this); } }); @@ -574,9 +568,6 @@ cc.LayerGradient = cc.LayerColor.extend(/** @lends cc.LayerGradient# */{ }, _createRenderCmd: function(){ - if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new cc.LayerGradient.CanvasRenderCmd(this); - else return new cc.LayerGradient.WebGLRenderCmd(this); } }); diff --git a/cocos2d/core/layers/CCLayerCanvasRenderCmd.js b/cocos2d/core/layers/CCLayerCanvasRenderCmd.js index 7ae79ca588..e69de29bb2 100644 --- a/cocos2d/core/layers/CCLayerCanvasRenderCmd.js +++ b/cocos2d/core/layers/CCLayerCanvasRenderCmd.js @@ -1,458 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -//-----------------------// -// 1. cc.Layer // -// 2. cc.LayerColor // -// 3. cc.LayerGradient // -//-----------------------// - -/** - * cc.Layer's rendering objects of Canvas - */ -(function(){ - //Layer's canvas render command - cc.Layer.CanvasRenderCmd = function(renderable){ - cc.Node.CanvasRenderCmd.call(this, renderable); - this._isBaked = false; - this._bakeSprite = null; - this._updateCache = 2; // 2: Updated child visit 1: Rendering 0: Nothing to do - }; - - var proto = cc.Layer.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype); - proto.constructor = cc.Layer.CanvasRenderCmd; - - proto._setCacheDirty = function(child){ - if(child && this._updateCache === 0) - this._updateCache = 2; - if (this._cacheDirty === false) { - this._cacheDirty = true; - var cachedP = this._cachedParent; - cachedP && cachedP !== this && cachedP._setNodeDirtyForCache && cachedP._setNodeDirtyForCache(); - } - }; - - proto.updateStatus = function () { - var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag; - if (locFlag & flags.orderDirty) { - this._cacheDirty = true; - if(this._updateCache === 0) - this._updateCache = 2; - this._dirtyFlag = this._dirtyFlag & flags.orderDirty ^ this._dirtyFlag; - } - - cc.Node.RenderCmd.prototype.updateStatus.call(this); - }; - - proto._syncStatus = function (parentCmd) { - var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag; - if (locFlag & flags.orderDirty) { - this._cacheDirty = true; - if(this._updateCache === 0) - this._updateCache = 2; - this._dirtyFlag = this._dirtyFlag & flags.orderDirty ^ this._dirtyFlag; - } - cc.Node.RenderCmd.prototype._syncStatus.call(this, parentCmd); - }; - - proto.transform = function (parentCmd, recursive) { - var wt = this._worldTransform; - var a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty; - cc.Node.CanvasRenderCmd.prototype.transform.call(this, parentCmd, recursive); - if(( wt.a !== a || wt.b !== b || wt.c !== c || wt.d !== d ) && this._updateCache === 0) - this._updateCache = 2; - }; - - proto.bake = function(){ - if (!this._isBaked) { - this._needDraw = true; - cc.renderer.childrenOrderDirty = true; - //limit: 1. its children's blendfunc are invalid. - this._isBaked = this._cacheDirty = true; - if(this._updateCache === 0) - this._updateCache = 2; - - var children = this._node._children; - for(var i = 0, len = children.length; i < len; i++) - children[i]._renderCmd._setCachedParent(this); - - if (!this._bakeSprite){ - this._bakeSprite = new cc.BakeSprite(); - this._bakeSprite.setAnchorPoint(0,0); - } - } - }; - - proto.unbake = function(){ - if (this._isBaked) { - cc.renderer.childrenOrderDirty = true; - this._needDraw = false; - this._isBaked = false; - this._cacheDirty = true; - if(this._updateCache === 0) - this._updateCache = 2; - - var children = this._node._children; - for(var i = 0, len = children.length; i < len; i++) - children[i]._renderCmd._setCachedParent(null); - } - }; - - proto.isBaked = function(){ - return this._isBaked; - }; - - proto.rendering = function(){ - if(this._cacheDirty){ - var node = this._node; - var children = node._children, locBakeSprite = this._bakeSprite; - - //compute the bounding box of the bake layer. - this.transform(this.getParentRenderCmd(), true); - - var boundingBox = this._getBoundingBoxForBake(); - boundingBox.width = 0|(boundingBox.width+0.5); - boundingBox.height = 0|(boundingBox.height+0.5); - - var bakeContext = locBakeSprite.getCacheContext(); - var ctx = bakeContext.getContext(); - - locBakeSprite.setPosition(boundingBox.x, boundingBox.y); - - if(this._updateCache > 0){ - locBakeSprite.resetCanvasSize(boundingBox.width, boundingBox.height); - bakeContext.setOffset(0 - boundingBox.x, ctx.canvas.height - boundingBox.height + boundingBox.y ); - //visit for canvas - node.sortAllChildren(); - cc.renderer._turnToCacheMode(this.__instanceId); - for (var i = 0, len = children.length; i < len; i++) { - children[i].visit(this); - } - cc.renderer._renderingToCacheCanvas(bakeContext, this.__instanceId); - locBakeSprite.transform(); //because bake sprite's position was changed at rendering. - this._updateCache--; - } - - this._cacheDirty = false; - } - }; - - proto.visit = function(parentCmd){ - if(!this._isBaked){ - cc.Node.CanvasRenderCmd.prototype.visit.call(this, parentCmd); - return; - } - - var node = this._node, children = node._children; - var len = children.length; - // quick return if not visible - if (!node._visible || len === 0) - return; - - this._syncStatus(parentCmd); - cc.renderer.pushRenderCommand(this); - - //the bakeSprite is drawing - this._bakeSprite.visit(this); - this._dirtyFlag = 0; - }; - - proto._bakeForAddChild = function(child){ - if(child._parent === this._node && this._isBaked) - child._renderCmd._setCachedParent(this); - }; - - proto._getBoundingBoxForBake = function(){ - var rect = null, node = this._node; - - //query child's BoundingBox - if (!node._children || node._children.length === 0) - return cc.rect(0, 0, 10, 10); - var trans = node.getNodeToWorldTransform(); - - var locChildren = node._children; - for (var i = 0, len = locChildren.length; i < len; i++) { - var child = locChildren[i]; - if (child && child._visible) { - if(rect){ - var childRect = child._getBoundingBoxToCurrentNode(trans); - if (childRect) - rect = cc.rectUnion(rect, childRect); - }else{ - rect = child._getBoundingBoxToCurrentNode(trans); - } - } - } - return rect; - }; -})(); - -/** - * cc.LayerColor's rendering objects of Canvas - */ -(function(){ - //LayerColor's canvas render command - cc.LayerColor.CanvasRenderCmd = function(renderable){ - cc.Layer.CanvasRenderCmd.call(this, renderable); - this._needDraw = true; - this._blendFuncStr = "source-over"; - this._bakeRenderCmd = new cc.CustomRenderCmd(this, this._bakeRendering); - }; - var proto = cc.LayerColor.CanvasRenderCmd.prototype = Object.create(cc.Layer.CanvasRenderCmd.prototype); - proto.constructor = cc.LayerColor.CanvasRenderCmd; - - proto.unbake = function(){ - cc.Layer.CanvasRenderCmd.prototype.unbake.call(this); - this._needDraw = true; - }; - - proto.rendering = function (ctx, scaleX, scaleY) { - var wrapper = ctx || cc._renderContext, context = wrapper.getContext(), - node = this._node, - curColor = this._displayedColor, - opacity = this._displayedOpacity / 255, - locWidth = node._contentSize.width, - locHeight = node._contentSize.height; - - if (opacity === 0) - return; - - wrapper.setCompositeOperation(this._blendFuncStr); - wrapper.setGlobalAlpha(opacity); - wrapper.setFillStyle("rgba(" + (0 | curColor.r) + "," + (0 | curColor.g) + "," - + (0 | curColor.b) + ", 1)"); //TODO: need cache the color string - - wrapper.setTransform(this._worldTransform, scaleX, scaleY); - context.fillRect(0, 0, locWidth * scaleX, -locHeight * scaleY); - - cc.g_NumberOfDraws++; - }; - - proto.updateBlendFunc = function(blendFunc){ - this._blendFuncStr = cc.Node.CanvasRenderCmd._getCompositeOperationByBlendFunc(blendFunc); - }; - - proto._updateSquareVertices = - proto._updateSquareVerticesWidth = - proto._updateSquareVerticesHeight = function(){}; - - proto._bakeRendering = function(){ - if(this._cacheDirty){ - var node = this._node; - var locBakeSprite = this._bakeSprite, children = node._children; - var len = children.length, i; - - //compute the bounding box of the bake layer. - this.transform(this.getParentRenderCmd(), true); - //compute the bounding box of the bake layer. - var boundingBox = this._getBoundingBoxForBake(); - boundingBox.width = 0|(boundingBox.width+0.5); - boundingBox.height = 0|(boundingBox.height+0.5); - - var bakeContext = locBakeSprite.getCacheContext(); - var ctx = bakeContext.getContext(); - - locBakeSprite.setPosition(boundingBox.x, boundingBox.y); - - if(this._updateCache > 0) { - ctx.fillStyle = bakeContext._currentFillStyle; - locBakeSprite.resetCanvasSize(boundingBox.width, boundingBox.height); - bakeContext.setOffset(0 - boundingBox.x, ctx.canvas.height - boundingBox.height + boundingBox.y ); - - var child; - cc.renderer._turnToCacheMode(this.__instanceId); - //visit for canvas - if (len > 0) { - node.sortAllChildren(); - // draw children zOrder < 0 - for (i = 0; i < len; i++) { - child = children[i]; - if (child._localZOrder < 0) - child._renderCmd.visit(this); - else - break; - } - cc.renderer.pushRenderCommand(this); - for (; i < len; i++) { - children[i]._renderCmd.visit(this); - } - } else - cc.renderer.pushRenderCommand(this); - cc.renderer._renderingToCacheCanvas(bakeContext, this.__instanceId); - locBakeSprite.transform(); - this._updateCache--; - } - this._cacheDirty = false; - } - }; - - proto.visit = function(parentCmd){ - if(!this._isBaked){ - cc.Node.CanvasRenderCmd.prototype.visit.call(this); - return; - } - - var node = this._node; - // quick return if not visible - if (!node._visible) - return; - - this._syncStatus(parentCmd); - - cc.renderer.pushRenderCommand(this._bakeRenderCmd); - - //the bakeSprite is drawing - this._bakeSprite._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty); - this._bakeSprite.visit(this); - this._dirtyFlag = 0; - }; - - proto._getBoundingBoxForBake = function(){ - var node = this._node; - //default size - var rect = cc.rect(0, 0, node._contentSize.width, node._contentSize.height); - var trans = node.getNodeToWorldTransform(); - rect = cc.rectApplyAffineTransform(rect, node.getNodeToWorldTransform()); - - //query child's BoundingBox - if (!node._children || node._children.length === 0) - return rect; - - var locChildren = node._children; - for (var i = 0; i < locChildren.length; i++) { - var child = locChildren[i]; - if (child && child._visible) { - var childRect = child._getBoundingBoxToCurrentNode(trans); - rect = cc.rectUnion(rect, childRect); - } - } - return rect; - }; -})(); - -/** - * cc.LayerGradient's rendering objects of Canvas - */ -(function(){ - cc.LayerGradient.RenderCmd = { - updateStatus: function () { - var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag; - if (locFlag & flags.gradientDirty) { - this._dirtyFlag |= flags.colorDirty; - this._dirtyFlag = this._dirtyFlag & flags.gradientDirty ^ this._dirtyFlag; - } - - cc.Node.RenderCmd.prototype.updateStatus.call(this); - } - }; - - cc.LayerGradient.CanvasRenderCmd = function(renderable){ - cc.LayerColor.CanvasRenderCmd.call(this, renderable); - this._needDraw = true; - this._startPoint = cc.p(0, 0); - this._endPoint = cc.p(0, 0); - this._startStopStr = null; - this._endStopStr = null; - }; - var proto = cc.LayerGradient.CanvasRenderCmd.prototype = Object.create(cc.LayerColor.CanvasRenderCmd.prototype); - cc.inject(cc.LayerGradient.RenderCmd, proto); - proto.constructor = cc.LayerGradient.CanvasRenderCmd; - - proto.rendering = function (ctx, scaleX, scaleY) { - var wrapper = ctx || cc._renderContext, context = wrapper.getContext(), - node = this._node, - opacity = this._displayedOpacity / 255; - - if (opacity === 0) - return; - - var locWidth = node._contentSize.width, locHeight = node._contentSize.height; - wrapper.setCompositeOperation(this._blendFuncStr); - wrapper.setGlobalAlpha(opacity); - var gradient = context.createLinearGradient(this._startPoint.x*scaleX, this._startPoint.y*scaleY, this._endPoint.x*scaleX, this._endPoint.y*scaleY); - - if(node._colorStops){ //Should always fall here now - for(var i=0; i < node._colorStops.length; i++) { - var stop = node._colorStops[i]; - gradient.addColorStop(stop.p, this._colorStopsStr[i]); - } - }else{ - gradient.addColorStop(0, this._startStopStr); - gradient.addColorStop(1, this._endStopStr); - } - - wrapper.setFillStyle(gradient); - - wrapper.setTransform(this._worldTransform, scaleX, scaleY); - context.fillRect(0, 0, locWidth * scaleX, -locHeight * scaleY); - cc.g_NumberOfDraws++; - }; - - proto._syncStatus = function (parentCmd) { - var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag; - if (locFlag & flags.gradientDirty) { - this._dirtyFlag |= flags.colorDirty; - this._dirtyFlag = locFlag & flags.gradientDirty ^ locFlag; - } - - cc.Node.RenderCmd.prototype._syncStatus.call(this, parentCmd); - }; - - proto._updateColor = function(){ - var node = this._node; - var contentSize = node._contentSize; - var tWidth = contentSize.width * 0.5, tHeight = contentSize.height * 0.5; - this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.gradientDirty ^ this._dirtyFlag; - - //fix the bug of gradient layer - var angle = cc.pAngleSigned(cc.p(0, -1), node._alongVector); - var p1 = cc.pRotateByAngle(cc.p(0, -1), cc.p(0,0), angle); - var factor = Math.min(Math.abs(1 / p1.x), Math.abs(1/ p1.y)); - - this._startPoint.x = tWidth * (-p1.x * factor) + tWidth; - this._startPoint.y = tHeight * (p1.y * factor) - tHeight; - this._endPoint.x = tWidth * (p1.x * factor) + tWidth; - this._endPoint.y = tHeight * (-p1.y * factor) - tHeight; - - var locStartColor = this._displayedColor, locEndColor = node._endColor; - var startOpacity = node._startOpacity/255, endOpacity = node._endOpacity/255; - this._startStopStr = "rgba(" + Math.round(locStartColor.r) + "," + Math.round(locStartColor.g) + "," - + Math.round(locStartColor.b) + "," + startOpacity.toFixed(4) + ")"; - this._endStopStr = "rgba(" + Math.round(locEndColor.r) + "," + Math.round(locEndColor.g) + "," - + Math.round(locEndColor.b) + "," + endOpacity.toFixed(4) + ")"; - - if( node._colorStops){ - this._startOpacity = 0; - this._endOpacity = 0; - - this._colorStopsStr = []; - for(var i =0; i < node._colorStops.length; i++){ - var stopColor = node._colorStops[i].color; - var stopOpacity = stopColor.a == null ? 1 : stopColor.a / 255; - this._colorStopsStr.push("rgba(" + Math.round(stopColor.r) + "," + Math.round(stopColor.g) + "," - + Math.round(stopColor.b) + "," + stopOpacity.toFixed(4) + ")"); - } - } - }; -})(); \ No newline at end of file diff --git a/cocos2d/core/platform/CCConfig.js b/cocos2d/core/platform/CCConfig.js index 5c4b185739..59e08703d4 100644 --- a/cocos2d/core/platform/CCConfig.js +++ b/cocos2d/core/platform/CCConfig.js @@ -56,7 +56,7 @@ window["CocosEngine"] = cc.ENGINE_VERSION = "Cocos2d-JS v3.10"; * @constant * @type {Number} */ -cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL = 0; +cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL = 1; /** * Position of the FPS (Default: 0,0 (bottom-left corner))
@@ -300,4 +300,4 @@ cc.ENABLE_STACKABLE_ACTIONS = 1; * @constant * @type {Number} */ -cc.ENABLE_GL_STATE_CACHE = 1; \ No newline at end of file +cc.ENABLE_GL_STATE_CACHE = 1; diff --git a/cocos2d/core/platform/CCEGLView.js b/cocos2d/core/platform/CCEGLView.js index cc76c6fb54..1fe5e45a77 100644 --- a/cocos2d/core/platform/CCEGLView.js +++ b/cocos2d/core/platform/CCEGLView.js @@ -956,12 +956,6 @@ cc.ContentStrategy = cc.Class.extend(/** @lends cc.ContentStrategy# */{ Math.round((containerH - contentH) / 2), contentW, contentH); - // Translate the content - if (cc._renderType === cc.game.RENDER_TYPE_CANVAS){ - //TODO: modify something for setTransform - //cc._renderContext.translate(viewport.x, viewport.y + contentH); - } - this._result.scale = [scaleX, scaleY]; this._result.viewport = viewport; return this._result; diff --git a/cocos2d/core/platform/CCMacro.js b/cocos2d/core/platform/CCMacro.js index f0e0a7c7f4..8faecf0326 100644 --- a/cocos2d/core/platform/CCMacro.js +++ b/cocos2d/core/platform/CCMacro.js @@ -562,11 +562,40 @@ cc.VERTEX_ATTRIB_COLOR = 1; * @type {Number} */ cc.VERTEX_ATTRIB_TEX_COORDS = 2; + +/** + * PITFOREST + * @constant + * @type {Number} + */ +cc.VERTEX_ATTRIB_MVMAT0 = 3; + +/** + * PITFOREST + * @constant + * @type {Number} + */ +cc.VERTEX_ATTRIB_MVMAT1 = 4; + +/** + * PITFOREST + * @constant + * @type {Number} + */ +cc.VERTEX_ATTRIB_MVMAT2 = 5; + /** + * PITFOREST * @constant * @type {Number} */ -cc.VERTEX_ATTRIB_MAX = 3; +cc.VERTEX_ATTRIB_MVMAT3 = 6; + +/** + * @constant + * @type {Number} + */ +cc.VERTEX_ATTRIB_MAX = 7; //------------Uniforms------------------ /** @@ -626,6 +655,13 @@ cc.SHADER_POSITION_TEXTURECOLOR = "ShaderPositionTextureColor"; * @type {String} */ cc.SHADER_POSITION_TEXTURECOLORALPHATEST = "ShaderPositionTextureColorAlphaTest"; + +/** + * PITFOREST + * @constant + * @type {String} + */ +cc.SHADER_POSITION_TEXTURECOLORALPHATEST_BATCHED = "ShaderPositionTextureColorAlphaTestBatched"; /** * @constant * @type {String} @@ -721,6 +757,13 @@ cc.ATTRIBUTE_NAME_POSITION = "a_position"; */ cc.ATTRIBUTE_NAME_TEX_COORD = "a_texCoord"; +/** + * PITFOREST + * @constant + * @type {String} + */ +cc.ATTRIBUTE_NAME_MVMAT = "a_mvMatrix"; + /** * default size for font size diff --git a/cocos2d/core/platform/CCTypes.js b/cocos2d/core/platform/CCTypes.js index 99aa6e86fd..306c971ce3 100644 --- a/cocos2d/core/platform/CCTypes.js +++ b/cocos2d/core/platform/CCTypes.js @@ -394,12 +394,4 @@ cc.FontDefinition = function (properties) { cc.FontDefinition.prototype._getCanvasFontStr = function(){ var lineHeight = !this.lineHeight.charAt ? this.lineHeight+"px" : this.lineHeight; return this.fontStyle + " " + this.fontWeight + " " + this.fontSize + "px/"+lineHeight+" '" + this.fontName + "'"; -}; - -cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { - if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) { - cc.assert(cc.isFunction(cc._tmp.PrototypeColor), cc._LogInfos.MissingFile, "CCTypesPropertyDefine.js"); - cc._tmp.PrototypeColor(); - delete cc._tmp.PrototypeColor; - } -}); +}; \ No newline at end of file diff --git a/cocos2d/core/renderer/RendererWebGL.js b/cocos2d/core/renderer/RendererWebGL.js index af7e354eea..fb6c088d3d 100644 --- a/cocos2d/core/renderer/RendererWebGL.js +++ b/cocos2d/core/renderer/RendererWebGL.js @@ -47,8 +47,34 @@ cc.rendererWebGL = { i, len; var context = ctx || cc._renderContext; - for (i = 0, len = locCmds.length; i < len; i++) { - locCmds[i].rendering(context); + + //prepare batching + for (i = 0, len = locCmds.length; i< len; ++i) + { + var cmd = locCmds[i]; + if(!cmd._batched && cmd.configureBatch) //may be set to true by processed cmds during this loop + { + cmd.configureBatch(locCmds,i); + } + } + + for (i = 0, len = locCmds.length; i< len; ++i) { + var cmd = locCmds[i]; + if(cmd._batching) + { + cmd.batchedRendering(context); + } + else if(!cmd._batched) + { + cmd.rendering(context); + } + } + + //prepare batching + for (i = 0, len = locCmds.length; i< len; ++i) + { + locCmds[i]._batched = false; + locCmds[i]._batching = false; } }, diff --git a/cocos2d/core/sprites/CCSprite.js b/cocos2d/core/sprites/CCSprite.js index c6082ccd83..0003c886ec 100644 --- a/cocos2d/core/sprites/CCSprite.js +++ b/cocos2d/core/sprites/CCSprite.js @@ -314,25 +314,7 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{ if (this._reorderChildDirty) { var _children = this._children; - // insertion sort - var len = _children.length, i, j, tmp; - for(i=1; i= 0){ - if(tmp._localZOrder < _children[j]._localZOrder){ - _children[j+1] = _children[j]; - }else if(tmp._localZOrder === _children[j]._localZOrder && tmp.arrivalOrder < _children[j].arrivalOrder){ - _children[j+1] = _children[j]; - }else{ - break; - } - j--; - } - _children[j+1] = tmp; - } + cc.Node.prototype.sortAllChildren.call(this); if (this._batchNode) { this._arrayMakeObjectsPerformSelector(_children, cc.Node._stateCallbackType.sortAllChildren); @@ -357,9 +339,6 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{ return; } - if (zOrder === child.zIndex) - return; - if (this._batchNode && !this._reorderChildDirty) { this._setReorderChildDirtyRecursively(); this._batchNode.reorderBatch(true); @@ -976,10 +955,7 @@ cc.Sprite = cc.Node.extend(/** @lends cc.Sprite# */{ }, _createRenderCmd: function(){ - if(cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new cc.Sprite.CanvasRenderCmd(this); - else - return new cc.Sprite.WebGLRenderCmd(this); + return new cc.Sprite.BasicWebGLRenderCmd(this); } }); diff --git a/cocos2d/core/sprites/CCSpriteBatchNode.js b/cocos2d/core/sprites/CCSpriteBatchNode.js index 5bbfd89784..36569a6b24 100644 --- a/cocos2d/core/sprites/CCSpriteBatchNode.js +++ b/cocos2d/core/sprites/CCSpriteBatchNode.js @@ -627,9 +627,7 @@ cc.SpriteBatchNode = cc.Node.extend(/** @lends cc.SpriteBatchNode# */{ }, _createRenderCmd: function(){ - if(cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new cc.SpriteBatchNode.CanvasRenderCmd(this); - else + return new cc.SpriteBatchNode.WebGLRenderCmd(this); } }); diff --git a/cocos2d/core/sprites/CCSpriteBatchNodeCanvasRenderCmd.js b/cocos2d/core/sprites/CCSpriteBatchNodeCanvasRenderCmd.js index facfbb0277..e69de29bb2 100644 --- a/cocos2d/core/sprites/CCSpriteBatchNodeCanvasRenderCmd.js +++ b/cocos2d/core/sprites/CCSpriteBatchNodeCanvasRenderCmd.js @@ -1,100 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -(function(){ - //SpriteBatchNode's canvas render command - cc.SpriteBatchNode.CanvasRenderCmd = function(renderable){ - cc.Node.CanvasRenderCmd.call(this, renderable); - - this._texture = null; - this._textureToRender = null; - }; - - var proto = cc.SpriteBatchNode.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype); - proto.constructor = cc.SpriteBatchNode.CanvasRenderCmd; - - proto.checkAtlasCapacity = function(){}; - - proto.isValidChild = function(child){ - if (!(child instanceof cc.Sprite)) { - cc.log(cc._LogInfos.Sprite_addChild_4); - return false; - } - return true; - }; - - proto.initWithTexture = function(texture, capacity){ - this._textureToRender = this._texture = texture; - }; - - proto.insertQuad = function(sprite, index){}; - - proto.increaseAtlasCapacity = function(){}; - - proto.removeQuadAtIndex = function(){}; - - proto.removeAllQuads = function(){}; - - proto.getTexture = function(){ - return this._texture; - }; - - proto.setTexture = function(texture){ - this._texture = texture; - var locChildren = this._node._children; - for (var i = 0; i < locChildren.length; i++) - locChildren[i].setTexture(texture); - }; - - proto.updateChildrenAtlasIndex = function(children){ - this._node._descendants.length = 0; - //update _descendants after sortAllChildren - for (var i = 0, len = children.length; i < len; i++) - this._updateAtlasIndex(children[i]); - }; - - proto._updateAtlasIndex = function (sprite) { - var locDescendants = this._node._descendants; - var pArray = sprite.children, i, len = pArray.length; - for (i = 0; i < len; i++) { - if (pArray[i]._localZOrder < 0) { - locDescendants.push(pArray[i]); - } else - break - } - locDescendants.push(sprite); - for (; i < len; i++) { - locDescendants.push(pArray[i]); - } - }; - - proto.getTextureAtlas = function(){}; - - proto.setTextureAtlas = function(textureAtlas){}; - - proto.cutting = function(sprite, index){ - var node = this._node; - node._children.splice(index, 0, sprite); - } -})(); \ No newline at end of file diff --git a/cocos2d/core/sprites/CCSpriteBatchNodeWebGLRenderCmd.js b/cocos2d/core/sprites/CCSpriteBatchNodeWebGLRenderCmd.js index d61973d7e7..ba3afdedbd 100644 --- a/cocos2d/core/sprites/CCSpriteBatchNodeWebGLRenderCmd.js +++ b/cocos2d/core/sprites/CCSpriteBatchNodeWebGLRenderCmd.js @@ -35,7 +35,7 @@ proto.constructor = cc.SpriteBatchNode.WebGLRenderCmd; proto.isValidChild = function(child){ - if (!(child instanceof cc.Sprite)) { + if (!(child instanceof cc.Sprite || child instanceof cc.Node)) { cc.log(cc._LogInfos.Sprite_addChild_4); return false; } @@ -77,7 +77,8 @@ this.transform(parentCmd); this.updateStatus(parentCmd); //because batchNode doesn't visit its children. currentStack.top = this._stackMatrix; - + + node._reorderChildDirty = true; node.sortAllChildren(); cc.renderer.pushRenderCommand(this); diff --git a/cocos2d/core/sprites/CCSpriteCanvasRenderCmd.js b/cocos2d/core/sprites/CCSpriteCanvasRenderCmd.js index eca55cd61d..e69de29bb2 100644 --- a/cocos2d/core/sprites/CCSpriteCanvasRenderCmd.js +++ b/cocos2d/core/sprites/CCSpriteCanvasRenderCmd.js @@ -1,307 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -(function() { - cc.Sprite.CanvasRenderCmd = function (renderable) { - cc.Node.CanvasRenderCmd.call(this, renderable); - this._needDraw = true; - this._textureCoord = { - renderX: 0, //the x of texture coordinate for render, when texture tinted, its value doesn't equal x. - renderY: 0, //the y of texture coordinate for render, when texture tinted, its value doesn't equal y. - x: 0, //the x of texture coordinate for node. - y: 0, //the y of texture coordinate for node. - width: 0, - height: 0, - validRect: false - }; - this._blendFuncStr = "source-over"; - this._colorized = false; - - this._textureToRender = null; - }; - - var proto = cc.Sprite.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype); - proto.constructor = cc.Sprite.CanvasRenderCmd; - - proto._init = function () {}; - - proto.setDirtyRecursively = function (value) {}; - - proto._resetForBatchNode = function () {}; - - proto._setTexture = function (texture) { - var node = this._node; - if (node._texture !== texture) { - if (texture) { - node._textureLoaded = texture._textureLoaded; - }else{ - node._textureLoaded = false; - } - node._texture = texture; - this._updateColor(); - } - }; - - proto._setColorDirty = function () { - this.setDirtyFlag(cc.Node._dirtyFlags.colorDirty | cc.Node._dirtyFlags.opacityDirty); - }; - - proto.isFrameDisplayed = function (frame) { //TODO there maybe has a bug - var node = this._node; - if (frame.getTexture() !== node._texture) - return false; - return cc.rectEqualToRect(frame.getRect(), node._rect); - }; - - proto.updateBlendFunc = function (blendFunc) { - this._blendFuncStr = cc.Node.CanvasRenderCmd._getCompositeOperationByBlendFunc(blendFunc); - }; - - proto._setBatchNodeForAddChild = function (child) { - return true; - }; - - proto._handleTextureForRotatedTexture = function (texture, rect, rotated, counterclockwise) { - if (rotated && texture.isLoaded()) { - var tempElement = texture.getHtmlElementObj(); - tempElement = cc.Sprite.CanvasRenderCmd._cutRotateImageToCanvas(tempElement, rect, counterclockwise); - var tempTexture = new cc.Texture2D(); - tempTexture.initWithElement(tempElement); - tempTexture.handleLoadedTexture(); - texture = tempTexture; - rect.x = rect.y = 0; - this._node._rect = cc.rect(0, 0, rect.width, rect.height); - } - return texture; - }; - - proto._checkTextureBoundary = function (texture, rect, rotated) { - if (texture && texture.url) { - var _x = rect.x + rect.width, _y = rect.y + rect.height; - if (_x > texture.width) - cc.error(cc._LogInfos.RectWidth, texture.url); - if (_y > texture.height) - cc.error(cc._LogInfos.RectHeight, texture.url); - } - }; - - proto.rendering = function (ctx, scaleX, scaleY) { - var node = this._node; - var locTextureCoord = this._textureCoord, alpha = (this._displayedOpacity / 255); - - var texture = this._textureToRender || node._texture; - - if ((texture && (locTextureCoord.width === 0 || locTextureCoord.height === 0|| !texture._textureLoaded)) || alpha === 0) - return; - - var wrapper = ctx || cc._renderContext, context = wrapper.getContext(); - var locX = node._offsetPosition.x, locHeight = node._rect.height, locWidth = node._rect.width, - locY = -node._offsetPosition.y - locHeight, image; - - wrapper.setTransform(this._worldTransform, scaleX, scaleY); - wrapper.setCompositeOperation(this._blendFuncStr); - wrapper.setGlobalAlpha(alpha); - - if(node._flippedX || node._flippedY) - wrapper.save(); - if (node._flippedX) { - locX = -locX - locWidth; - context.scale(-1, 1); - } - if (node._flippedY) { - locY = node._offsetPosition.y; - context.scale(1, -1); - } - - var sx, sy, sw, sh, x, y, w, h; - if (this._colorized) { - sx = 0; - sy = 0; - }else{ - sx = locTextureCoord.renderX; - sy = locTextureCoord.renderY; - } - sw = locTextureCoord.width; - sh = locTextureCoord.height; - - x = locX * scaleX; - y = locY * scaleY; - w = locWidth * scaleX; - h = locHeight * scaleY; - - if (texture) { - image = texture._htmlElementObj; - if (texture._pattern !== "") { - wrapper.setFillStyle(context.createPattern(image, texture._pattern)); - context.fillRect(x, y, w, h); - } else { - context.drawImage(image, - sx, sy, sw, sh, - x, y, w, h); - } - } else { - var contentSize = node._contentSize; - if (locTextureCoord.validRect) { - var curColor = this._displayedColor; - wrapper.setFillStyle("rgba(" + curColor.r + "," + curColor.g + "," + curColor.b + ",1)"); - context.fillRect(x, y, contentSize.width * scaleX, contentSize.height * scaleY); - } - } - if(node._flippedX || node._flippedY) - wrapper.restore(); - cc.g_NumberOfDraws++; - }; - - proto._updateColor = function(){ - var node = this._node; - - var texture = node._texture, rect = this._textureCoord; - var dColor = this._displayedColor; - - if(texture){ - if(dColor.r !== 255 || dColor.g !== 255 || dColor.b !== 255){ - this._textureToRender = texture._generateColorTexture(dColor.r, dColor.g, dColor.b, rect); - this._colorized = true; - }else if(texture){ - this._textureToRender = texture; - this._colorized = false; - } - } - }; - - proto.getQuad = function () { - //throw an error. it doesn't support this function. - return null; - }; - - proto._updateForSetSpriteFrame = function (pNewTexture, textureLoaded){ - this._colorized = false; - this._textureCoord.renderX = this._textureCoord.x; - this._textureCoord.renderY = this._textureCoord.y; - textureLoaded = textureLoaded || pNewTexture._textureLoaded; - if (textureLoaded) { - var curColor = this._node.getColor(); - if (curColor.r !== 255 || curColor.g !== 255 || curColor.b !== 255) - this._updateColor(); - } - }; - - proto.updateTransform = function () { //TODO need delete, because Canvas needn't - var _t = this, node = this._node; - - // re-calculate matrix only if it is dirty - if (node.dirty) { - // If it is not visible, or one of its ancestors is not visible, then do nothing: - var locParent = node._parent; - if (!node._visible || ( locParent && locParent !== node._batchNode && locParent._shouldBeHidden)) { - node._shouldBeHidden = true; - } else { - node._shouldBeHidden = false; - - if (!locParent || locParent === node._batchNode) { - node._transformToBatch = _t.getNodeToParentTransform(); - } else { - //cc.assert(_t._parent instanceof cc.Sprite, "Logic error in CCSprite. Parent must be a CCSprite"); - node._transformToBatch = cc.affineTransformConcat(_t.getNodeToParentTransform(), locParent._transformToBatch); - } - } - node._recursiveDirty = false; - node.dirty = false; - } - - // recursively iterate over children - if (node._hasChildren) - node._arrayMakeObjectsPerformSelector(node._children, cc.Node._stateCallbackType.updateTransform); - }; - - proto._spriteFrameLoadedCallback = function (spriteFrame) { - var node = this; - node.setTextureRect(spriteFrame.getRect(), spriteFrame.isRotated(), spriteFrame.getOriginalSize()); - - node._renderCmd._updateColor(); - node.dispatchEvent("load"); - }; - - proto._textureLoadedCallback = function (sender) { - var node = this; - if (node._textureLoaded) - return; - - node._textureLoaded = true; - var locRect = node._rect, locRenderCmd = this._renderCmd; - if (!locRect) { - locRect = cc.rect(0, 0, sender.width, sender.height); - } else if (cc._rectEqualToZero(locRect)) { - locRect.width = sender.width; - locRect.height = sender.height; - } - - node.texture = sender; - node.setTextureRect(locRect, node._rectRotated); - - //set the texture's color after the it loaded - var locColor = locRenderCmd._displayedColor; - if (locColor.r !== 255 || locColor.g !== 255 || locColor.b !== 255) - locRenderCmd._updateColor(); - - // by default use "Self Render". - // if the sprite is added to a batchnode, then it will automatically switch to "batchnode Render" - node.setBatchNode(node._batchNode); - node.dispatchEvent("load"); - }; - - proto._setTextureCoords = function (rect, needConvert) { - if (needConvert === undefined) - needConvert = true; - var locTextureRect = this._textureCoord, - scaleFactor = needConvert ? cc.contentScaleFactor() : 1; - locTextureRect.renderX = locTextureRect.x = 0 | (rect.x * scaleFactor); - locTextureRect.renderY = locTextureRect.y = 0 | (rect.y * scaleFactor); - locTextureRect.width = 0 | (rect.width * scaleFactor); - locTextureRect.height = 0 | (rect.height * scaleFactor); - locTextureRect.validRect = !(locTextureRect.width === 0 || locTextureRect.height === 0 || locTextureRect.x < 0 || locTextureRect.y < 0); - }; - - cc.Sprite.CanvasRenderCmd._cutRotateImageToCanvas = function (texture, rect, counterclockwise) { - if (!texture) - return null; - - if (!rect) - return texture; - - counterclockwise = counterclockwise == null? true: counterclockwise; // texture package is counterclockwise, spine is clockwise - - var nCanvas = document.createElement("canvas"); - nCanvas.width = rect.width; - nCanvas.height = rect.height; - var ctx = nCanvas.getContext("2d"); - ctx.translate(nCanvas.width / 2, nCanvas.height / 2); - if(counterclockwise) - ctx.rotate(-1.5707963267948966); - else - ctx.rotate(1.5707963267948966); - ctx.drawImage(texture, rect.x, rect.y, rect.height, rect.width, -rect.height / 2, -rect.width / 2, rect.height, rect.width); - return nCanvas; - }; -})(); diff --git a/cocos2d/core/sprites/CCSpriteFrame.js b/cocos2d/core/sprites/CCSpriteFrame.js index a203e7d439..b2c19fd731 100644 --- a/cocos2d/core/sprites/CCSpriteFrame.js +++ b/cocos2d/core/sprites/CCSpriteFrame.js @@ -243,17 +243,6 @@ cc.SpriteFrame = cc.Class.extend(/** @lends cc.SpriteFrame# */{ if(!locLoaded){ texture.addEventListener("load", function(sender){ this._textureLoaded = true; - if(this._rotated && cc._renderType === cc.game.RENDER_TYPE_CANVAS){ - var tempElement = sender.getHtmlElementObj(); - tempElement = cc.Sprite.CanvasRenderCmd._cutRotateImageToCanvas(tempElement, this.getRect()); - var tempTexture = new cc.Texture2D(); - tempTexture.initWithElement(tempElement); - tempTexture.handleLoadedTexture(); - this.setTexture(tempTexture); - - var rect = this.getRect(); - this.setRect(cc.rect(0, 0, rect.width, rect.height)); - } var locRect = this._rect; if(locRect.width === 0 && locRect.height === 0){ var w = sender.width, h = sender.height; diff --git a/cocos2d/core/sprites/CCSpriteFrameCache.js b/cocos2d/core/sprites/CCSpriteFrameCache.js index 6152c54b23..5aa7a3e508 100644 --- a/cocos2d/core/sprites/CCSpriteFrameCache.js +++ b/cocos2d/core/sprites/CCSpriteFrameCache.js @@ -179,22 +179,7 @@ cc.spriteFrameCache = /** @lends cc.spriteFrameCache# */{ spAliases[alias] = key; } } - - if (cc._renderType === cc.game.RENDER_TYPE_CANVAS && spriteFrame.isRotated()) { - //clip to canvas - var locTexture = spriteFrame.getTexture(); - if (locTexture.isLoaded()) { - var tempElement = spriteFrame.getTexture().getHtmlElementObj(); - tempElement = cc.Sprite.CanvasRenderCmd._cutRotateImageToCanvas(tempElement, spriteFrame.getRectInPixels()); - var tempTexture = new cc.Texture2D(); - tempTexture.initWithElement(tempElement); - tempTexture.handleLoadedTexture(); - spriteFrame.setTexture(tempTexture); - - var rect = spriteFrame._rect; - spriteFrame.setRect(cc.rect(0, 0, rect.width, rect.height)); - } - } + spriteFrames[key] = spriteFrame; } } diff --git a/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js b/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js index dd2f33e712..d47ab81f10 100644 --- a/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js +++ b/cocos2d/core/sprites/CCSpriteWebGLRenderCmd.js @@ -24,21 +24,96 @@ //Sprite's WebGL render command (function() { + cc.Sprite.WebGLRenderCmd = function (renderable) { cc.Node.WebGLRenderCmd.call(this, renderable); this._needDraw = true; this._quad = new cc.V3F_C4B_T2F_Quad(); + this._quadBufferView = new Uint32Array(this._quad.arrayBuffer); this._quadWebBuffer = cc._renderContext.createBuffer(); this._quadDirty = true; this._dirty = false; this._recursiveDirty = false; + this._supportsBatching = true; + this._batchShader = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLORALPHATEST_BATCHED); + this._matLocation = gl.getAttribLocation(this._batchShader._programObj, cc.ATTRIBUTE_NAME_MVMAT); + this._batchElementBuffer = null; + this._batchBuffer = null; }; var proto = cc.Sprite.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype); + proto.constructor = cc.Sprite.WebGLRenderCmd; proto.updateBlendFunc = function (blendFunc) {}; + + proto.batchBufferPool = []; + + //creates webgl buffers and initializes their size to what is properly required for each sprite + proto.createBatchBuffer = function(numSprites) + { + var arrayBuffer = gl.createBuffer(); + var elementBuffer = gl.createBuffer(); + + this.initBatchBuffers(arrayBuffer,elementBuffer,numSprites); + + return {arrayBuffer: arrayBuffer, elementBuffer: elementBuffer, size: numSprites }; + } + + proto.initBatchBuffers = function(arrayBuffer, elementBuffer, numSprites) + { + gl.bindBuffer(gl.ARRAY_BUFFER, arrayBuffer); + gl.bufferData(gl.ARRAY_BUFFER, this.byteSizePerSprite * numSprites ,gl.DYNAMIC_DRAW); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indicesPerSprite * 2 * numSprites, gl.DYNAMIC_DRAW); //*2 because we use shorts for indices + } + + //returns an object with {arrayBuffer, elementBuffer, size}, where size denotes how many sprites fit in the buffer (no need for bufferData if it's already big enough, bufferSubData enough) + proto.getBatchBuffer = function(numSprites) + { + var pool = this.batchBufferPool; + if(pool.length <=0) + { + return this.createBatchBuffer(numSprites); + } + else + { + var minBuf = null; //we also track the smallest found buffer because that one will be re-initialized and returned if no fitting buffer can be found + var minSize = Number.MAX_VALUE; + var minBufIndex = -1; + for(var i=pool.length-1;i>=0;--i) + { + var buf = pool[i]; + if(buf.size >= numSprites) + { + pool.removeByLastSwap(i); + return buf; + } + + if(buf.size < minSize) + { + minSize = buf.size; + minBuf = buf; + minBufIndex = i; + } + } + + //we only get here if no properly sized buffer was found + //in that case, take smallest buffer in pool, resize it and return it + pool.removeByLastSwap(minBufIndex); + this.initBatchBuffers(minBuf.arrayBuffer,minBuf.elementBuffer,numSprites); + minBuf.size = numSprites; + return minBuf; + } + } + + proto.storeBatchBuffer = function(buffer) + { + var pool = this.batchBufferPool; + pool.push(buffer); + } proto.setDirtyFlag = function(dirtyFlag){ cc.Node.WebGLRenderCmd.prototype.setDirtyFlag.call(this, dirtyFlag); @@ -303,7 +378,7 @@ } if (texture) - this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLOR); + this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLORALPHATEST); else this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_COLOR); @@ -419,16 +494,13 @@ proto.rendering = function (ctx) { var node = this._node, locTexture = node._texture; - if ((locTexture &&!locTexture._textureLoaded) || this._displayedOpacity === 0) - return; - - var gl = ctx || cc._renderContext ; - //cc.assert(!_t._batchNode, "If cc.Sprite is being rendered by cc.SpriteBatchNode, cc.Sprite#draw SHOULD NOT be called"); - if (locTexture) { - if (locTexture._textureLoaded) { - this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix); + var gl = ctx; + + var program = this._shaderProgram; + if (locTexture) { + program.use(); + program._setUniformForMVPMatrixWithMat4(this._stackMatrix); cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst); //optimize performance for javascript @@ -444,10 +516,10 @@ gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, true, 24, 12); //cc.VERTEX_ATTRIB_COLOR gl.vertexAttribPointer(2, 2, gl.FLOAT, false, 24, 16); //cc.VERTEX_ATTRIB_TEX_COORDS gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - } + } else { - this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix); + program.use(); + program._setUniformForMVPMatrixWithMat4(this._stackMatrix); cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst); cc.glBindTexture2D(null); @@ -463,34 +535,8 @@ gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 24, 12); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); } + + cc.g_NumberOfDraws++; - - if (cc.SPRITE_DEBUG_DRAW === 0 && !node._showNode) - return; - - cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW); - //cc.kmGLPushMatrixWitMat4(node._stackMatrix); - cc.current_stack.stack.push(cc.current_stack.top); - cc.current_stack.top = this._stackMatrix; - - if (cc.SPRITE_DEBUG_DRAW === 1 || node._showNode) { - // draw bounding box - var locQuad = this._quad; - var verticesG1 = [ - cc.p(locQuad.tl.vertices.x, locQuad.tl.vertices.y), - cc.p(locQuad.bl.vertices.x, locQuad.bl.vertices.y), - cc.p(locQuad.br.vertices.x, locQuad.br.vertices.y), - cc.p(locQuad.tr.vertices.x, locQuad.tr.vertices.y) - ]; - cc._drawingUtil.drawPoly(verticesG1, 4, true); - } else if (cc.SPRITE_DEBUG_DRAW === 2) { - // draw texture box - var drawRectG2 = node.getTextureRect(); - var offsetPixG2 = node.getOffsetPosition(); - var verticesG2 = [cc.p(offsetPixG2.x, offsetPixG2.y), cc.p(offsetPixG2.x + drawRectG2.width, offsetPixG2.y), - cc.p(offsetPixG2.x + drawRectG2.width, offsetPixG2.y + drawRectG2.height), cc.p(offsetPixG2.x, offsetPixG2.y + drawRectG2.height)]; - cc._drawingUtil.drawPoly(verticesG2, 4, true); - } // CC_SPRITE_DEBUG_DRAW - cc.current_stack.top = cc.current_stack.stack.pop(); }; })(); \ No newline at end of file diff --git a/cocos2d/core/textures/CCTexture2D.js b/cocos2d/core/textures/CCTexture2D.js index 9cbf90e222..6209becc00 100644 --- a/cocos2d/core/textures/CCTexture2D.js +++ b/cocos2d/core/textures/CCTexture2D.js @@ -98,514 +98,15 @@ cc.PVRHaveAlphaPremultiplied_ = false; cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { - if(cc._renderType === cc.game.RENDER_TYPE_CANVAS) { - - var proto = { - _contentSize: null, - _textureLoaded: false, - _htmlElementObj: null, - url: null, - _pattern: null, - - ctor: function () { - this._contentSize = cc.size(0, 0); - this._textureLoaded = false; - this._htmlElementObj = null; - this._pattern = ""; - }, - - /** - * get width in pixels - * @return {Number} - */ - getPixelsWide: function () { - return this._contentSize.width; - }, - - /** - * get height of in pixels - * @return {Number} - */ - getPixelsHigh: function () { - return this._contentSize.height; - }, - - /** - * get content size - * @returns {cc.Size} - */ - getContentSize: function () { - var locScaleFactor = cc.contentScaleFactor(); - return cc.size(this._contentSize.width / locScaleFactor, this._contentSize.height / locScaleFactor); - }, - - _getWidth: function () { - return this._contentSize.width / cc.contentScaleFactor(); - }, - _getHeight: function () { - return this._contentSize.height / cc.contentScaleFactor(); - }, - - /** - * get content size in pixels - * @returns {cc.Size} - */ - getContentSizeInPixels: function () { - return this._contentSize; - }, - - /** - * init with HTML element - * @param {HTMLImageElement|HTMLCanvasElement} element - */ - initWithElement: function (element) { - if (!element) - return; - this._htmlElementObj = element; - this._contentSize.width = element.width; - this._contentSize.height = element.height; - this._textureLoaded = true; - }, - - /** - * HTMLElement Object getter - * @return {HTMLImageElement|HTMLCanvasElement} - */ - getHtmlElementObj: function () { - return this._htmlElementObj; - }, - - /** - * check whether texture is loaded - * @returns {boolean} - */ - isLoaded: function () { - return this._textureLoaded; - }, - - /** - * handle loaded texture - */ - 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); - } - - var locElement = self._htmlElementObj; - self._contentSize.width = locElement.width; - self._contentSize.height = locElement.height; - - //dispatch load event to listener. - self.dispatchEvent("load"); - }, - - /** - * description of cc.Texture2D - * @returns {string} - */ - description: function () { - return ""; - }, - - initWithData: function (data, pixelFormat, pixelsWide, pixelsHigh, contentSize) { - //support only in WebGl rendering mode - return false; - }, - - initWithImage: function (uiImage) { - //support only in WebGl rendering mode - return false; - }, - - initWithString: function (text, fontName, fontSize, dimensions, hAlignment, vAlignment) { - //support only in WebGl rendering mode - return false; - }, - - releaseTexture: function () { - cc.loader.release(this.url); - }, - - getName: function () { - //support only in WebGl rendering mode - return null; - }, - - getMaxS: function () { - //support only in WebGl rendering mode - return 1; - }, - - setMaxS: function (maxS) { - //support only in WebGl rendering mode - }, - - getMaxT: function () { - return 1; - }, - - setMaxT: function (maxT) { - //support only in WebGl rendering mode - }, - - getPixelFormat: function () { - //support only in WebGl rendering mode - return null; - }, - - getShaderProgram: function () { - //support only in WebGl rendering mode - return null; - }, - - setShaderProgram: function (shaderProgram) { - //support only in WebGl rendering mode - }, - - hasPremultipliedAlpha: function () { - //support only in WebGl rendering mode - return false; - }, - - hasMipmaps: function () { - //support only in WebGl rendering mode - return false; - }, - - releaseData: function (data) { - //support only in WebGl rendering mode - data = null; - }, - - keepData: function (data, length) { - //support only in WebGl rendering mode - return data; - }, - - drawAtPoint: function (point) { - //support only in WebGl rendering mode - }, - - drawInRect: function (rect) { - //support only in WebGl rendering mode - }, - - /** - * init with ETC file - * @warning does not support on HTML5 - */ - initWithETCFile: function (file) { - cc.log(cc._LogInfos.Texture2D_initWithETCFile); - return false; - }, - - /** - * init with PVR file - * @warning does not support on HTML5 - */ - initWithPVRFile: function (file) { - cc.log(cc._LogInfos.Texture2D_initWithPVRFile); - return false; - }, - - /** - * init with PVRTC data - * @warning does not support on HTML5 - */ - initWithPVRTCData: function (data, level, bpp, hasAlpha, length, pixelFormat) { - cc.log(cc._LogInfos.Texture2D_initWithPVRTCData); - return false; - }, - - setTexParameters: function (texParams, magFilter, wrapS, wrapT) { - if(magFilter !== undefined) - texParams = {minFilter: texParams, magFilter: magFilter, wrapS: wrapS, wrapT: wrapT}; - - if(texParams.wrapS === cc.REPEAT && texParams.wrapT === cc.REPEAT){ - this._pattern = "repeat"; - return; - } - - if(texParams.wrapS === cc.REPEAT ){ - this._pattern = "repeat-x"; - return; - } - - if(texParams.wrapT === cc.REPEAT){ - this._pattern = "repeat-y"; - return; - } - - this._pattern = ""; - }, - - setAntiAliasTexParameters: function () { - //support only in WebGl rendering mode - }, - - setAliasTexParameters: function () { - //support only in WebGl rendering mode - }, - - generateMipmap: function () { - //support only in WebGl rendering mode - }, - - stringForFormat: function () { - //support only in WebGl rendering mode - return ""; - }, - - bitsPerPixelForFormat: function (format) { - //support only in WebGl rendering mode - return -1; - }, - - /** - * add listener for loaded event - * @param {Function} callback - * @param {cc.Node} target - * @deprecated since 3.1, please use addEventListener instead - */ - addLoadedEventListener: function (callback, target) { - this.addEventListener("load", callback, target); - }, - - /** - * remove listener from listeners by target - * @param {cc.Node} target - */ - removeLoadedEventListener: function (target) { - this.removeEventListener("load", target); - }, - - _generateColorTexture: function(){/*overide*/}, - _generateTextureCacheForColor: function(){ - if (this.channelCache) - return this.channelCache; - - var textureCache = [ - document.createElement("canvas"), - document.createElement("canvas"), - document.createElement("canvas"), - document.createElement("canvas") - ]; - //todo texture onload - renderToCache(this._htmlElementObj, textureCache); - return this.channelCache = textureCache; - }, - - //hack for gray effect - _grayElementObj: null, - _backupElement: null, - _isGray: false, - _switchToGray: function(toGray){ - if(!this._textureLoaded || this._isGray === toGray) - return; - this._isGray = toGray; - if(this._isGray){ - this._backupElement = this._htmlElementObj; - if(!this._grayElementObj) - this._grayElementObj = cc.Texture2D._generateGrayTexture(this._htmlElementObj); - this._htmlElementObj = this._grayElementObj; - } else { - if(this._backupElement !== null) - this._htmlElementObj = this._backupElement; - } - } - }; - - var renderToCache = function(image, cache){ - var w = image.width; - var h = image.height; - - cache[0].width = w; - cache[0].height = h; - cache[1].width = w; - cache[1].height = h; - cache[2].width = w; - cache[2].height = h; - cache[3].width = w; - cache[3].height = h; - - var cacheCtx = cache[3].getContext("2d"); - cacheCtx.drawImage(image, 0, 0); - var pixels = cacheCtx.getImageData(0, 0, w, h).data; - - var ctx; - for (var rgbI = 0; rgbI < 4; rgbI++) { - ctx = cache[rgbI].getContext("2d"); - - var to = ctx.getImageData(0, 0, w, h); - var data = to.data; - for (var i = 0; i < pixels.length; i += 4) { - data[i ] = (rgbI === 0) ? pixels[i ] : 0; - data[i + 1] = (rgbI === 1) ? pixels[i + 1] : 0; - data[i + 2] = (rgbI === 2) ? pixels[i + 2] : 0; - data[i + 3] = pixels[i + 3]; - } - ctx.putImageData(to, 0, 0); - } - image.onload = null; - }; - - //change color function - if(cc.sys._supportCanvasNewBlendModes){ - //multiply mode - //Primary afferent, Draw a new texture based on rect - proto._generateColorTexture = function(r, g, b, rect, canvas){ - var onlyCanvas = false; - if(canvas) - onlyCanvas = true; - else - canvas = document.createElement("canvas"); - var textureImage = this._htmlElementObj; - if(!rect) - rect = cc.rect(0, 0, textureImage.width, textureImage.height); - - canvas.width = rect.width; - canvas.height = rect.height; - - var context = canvas.getContext("2d"); - context.globalCompositeOperation = "source-over"; - context.fillStyle = "rgb(" + (r|0) + "," + (g|0) + "," + (b|0) + ")"; - context.fillRect(0, 0, rect.width, rect.height); - context.globalCompositeOperation = "multiply"; - context.drawImage( - textureImage, - rect.x, rect.y, rect.width, rect.height, - 0, 0, rect.width, rect.height - ); - context.globalCompositeOperation = "destination-atop"; - context.drawImage( - textureImage, - rect.x, rect.y, rect.width, rect.height, - 0, 0, rect.width, rect.height - ); - if(onlyCanvas) - return canvas; - var newTexture = new cc.Texture2D(); - newTexture.initWithElement(canvas); - newTexture.handleLoadedTexture(); - return newTexture; - }; - }else{ - //Four color map overlay - proto._generateColorTexture = function(r, g, b, rect, canvas){ - var onlyCanvas = false; - if(canvas) - onlyCanvas = true; - else - canvas = document.createElement("canvas"); - - var textureImage = this._htmlElementObj; - if(!rect) - rect = cc.rect(0, 0, textureImage.width, textureImage.height); - var x, y, w, h; - x = rect.x; y = rect.y; w = rect.width; h = rect.height; - if(!w || !h) - return; - - canvas.width = w; - canvas.height = h; - - var context = canvas.getContext("2d"); - var tintedImgCache = cc.textureCache.getTextureColors(this); - context.globalCompositeOperation = 'lighter'; - context.drawImage( - tintedImgCache[3], - x, y, w, h, - 0, 0, w, h - ); - if (r > 0) { - context.globalAlpha = r / 255; - context.drawImage( - tintedImgCache[0], - x, y, w, h, - 0, 0, w, h - ); - } - if (g > 0) { - context.globalAlpha = g / 255; - context.drawImage( - tintedImgCache[1], - x, y, w, h, - 0, 0, w, h - ); - } - if (b > 0) { - context.globalAlpha = b / 255; - context.drawImage( - tintedImgCache[2], - x, y, w, h, - 0, 0, w, h - ); - } - if(onlyCanvas) - return canvas; - - var newTexture = new cc.Texture2D(); - newTexture.initWithElement(canvas); - newTexture.handleLoadedTexture(); - return newTexture; - }; - } - - /** - *

- * This class allows to easily create OpenGL or Canvas 2D textures from images, text or raw data.
- * The created cc.Texture2D object will always have power-of-two dimensions.
- * Depending on how you create the cc.Texture2D object, the actual image area of the texture might be smaller than the texture dimensions
- * i.e. "contentSize" != (pixelsWide, pixelsHigh) and (maxS, maxT) != (1.0, 1.0).
- * Be aware that the content of the generated textures will be upside-down!

- * @name cc.Texture2D - * @class - * @extends cc.Class - * - * @property {WebGLTexture} name - <@readonly> WebGLTexture Object - * @property {Number} pixelFormat - <@readonly> Pixel format of the texture - * @property {Number} pixelsWidth - <@readonly> Width in pixels - * @property {Number} pixelsHeight - <@readonly> Height in pixels - * @property {Number} width - Content width in points - * @property {Number} height - Content height in points - * @property {cc.GLProgram} shaderProgram - The shader program used by drawAtPoint and drawInRect - * @property {Number} maxS - Texture max S - * @property {Number} maxT - Texture max T - */ - cc.Texture2D = cc.Class.extend(/** @lends cc.Texture2D# */proto); - - cc.Texture2D._generateGrayTexture = function(texture, rect, renderCanvas){ - if (texture === null) - return null; - renderCanvas = renderCanvas || document.createElement("canvas"); - rect = rect || cc.rect(0, 0, texture.width, texture.height); - renderCanvas.width = rect.width; - renderCanvas.height = rect.height; - - var context = renderCanvas.getContext("2d"); - context.drawImage(texture, rect.x, rect.y, rect.width, rect.height, 0, 0, rect.width, rect.height); - var imgData = context.getImageData(0, 0, rect.width, rect.height); - var data = imgData.data; - for (var i = 0, len = data.length; i < len; i += 4) { - data[i] = data[i + 1] = data[i + 2] = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2]; - } - context.putImageData(imgData, 0, 0); - return renderCanvas; - }; - - } else if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) { + if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) { cc.assert(cc.isFunction(cc._tmp.WebGLTexture2D), cc._LogInfos.MissingFile, "TexturesWebGL.js"); cc._tmp.WebGLTexture2D(); delete cc._tmp.WebGLTexture2D; - } - cc.EventHelper.prototype.apply(cc.Texture2D.prototype); + cc.EventHelper.prototype.apply(cc.Texture2D.prototype); - cc.assert(cc.isFunction(cc._tmp.PrototypeTexture2D), cc._LogInfos.MissingFile, "TexturesPropertyDefine.js"); - cc._tmp.PrototypeTexture2D(); - delete cc._tmp.PrototypeTexture2D; + cc.assert(cc.isFunction(cc._tmp.PrototypeTexture2D), cc._LogInfos.MissingFile, "TexturesPropertyDefine.js"); + cc._tmp.PrototypeTexture2D(); + delete cc._tmp.PrototypeTexture2D; + } }); diff --git a/cocos2d/core/textures/CCTextureCache.js b/cocos2d/core/textures/CCTextureCache.js index 3e80519bb3..894ff62fa3 100644 --- a/cocos2d/core/textures/CCTextureCache.js +++ b/cocos2d/core/textures/CCTextureCache.js @@ -306,75 +306,7 @@ cc.textureCache = /** @lends cc.textureCache# */{ }; cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { - if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) { - - var _p = cc.textureCache; - - _p.handleLoadedTexture = function (url) { - var locTexs = this._textures; - //remove judge - var tex = locTexs[url]; - if (!tex) { - tex = locTexs[url] = new cc.Texture2D(); - tex.url = url; - } - tex.handleLoadedTexture(); - }; - - /** - *

Returns a Texture2D object given an file image
- * If the file image was not previously loaded, it will create a new Texture2D
- * object and it will return it. It will use the filename as a key.
- * Otherwise it will return a reference of a previously loaded image.
- * Supported image extensions: .png, .jpg, .gif

- * @param {String} url - * @param {Function} cb - * @param {Object} target - * @return {cc.Texture2D} - * @example - * //example - * cc.textureCache.addImage("hello.png"); - */ - _p.addImage = function (url, cb, target) { - - cc.assert(url, cc._LogInfos.Texture2D_addImage); - - var locTexs = this._textures; - //remove judge - var tex = locTexs[url] || locTexs[cc.loader._getAliase(url)]; - if (tex) { - if(tex.isLoaded()) { - cb && cb.call(target, tex); - return tex; - } - else - { - tex.addEventListener("load", function(){ - cb && cb.call(target, tex); - }, target); - return tex; - } - } - - tex = locTexs[url] = new cc.Texture2D(); - tex.url = url; - var loadFunc = cc.loader._checkIsImageURL(url) ? cc.loader.load : cc.loader.loadImg; - loadFunc.call(cc.loader, url, function (err, img) { - if (err) - return cb && cb.call(target, err); - cc.textureCache.handleLoadedTexture(url); - - var texResult = locTexs[url]; - cb && cb.call(target, texResult); - }); - - return tex; - }; - - _p.addImageAsync = _p.addImage; - _p = null; - - } else if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) { + if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) { cc.assert(cc.isFunction(cc._tmp.WebGLTextureCache), cc._LogInfos.MissingFile, "TexturesWebGL.js"); cc._tmp.WebGLTextureCache(); delete cc._tmp.WebGLTextureCache; diff --git a/cocos2d/core/utils/CCProfiler.js b/cocos2d/core/utils/CCProfiler.js index 9e1925b55d..e4acf5a74c 100644 --- a/cocos2d/core/utils/CCProfiler.js +++ b/cocos2d/core/utils/CCProfiler.js @@ -21,6 +21,10 @@ cc.profiler = (function () { _SPFLabel = new cc.LabelTTF("0.000", "Arial", fontSize); _drawsLabel = new cc.LabelTTF("0000", "Arial", fontSize); + _FPSLabel.setVertexZ(0.9999); + _SPFLabel.setVertexZ(0.9999); + _drawsLabel.setVertexZ(0.9999); + _drawsLabel.setPosition(_drawsLabel.width / 2 + locStatsPosition.x, _drawsLabel.height * 5 / 2 + locStatsPosition.y); _SPFLabel.setPosition(_SPFLabel.width / 2 + locStatsPosition.x, _SPFLabel.height * 3 / 2 + locStatsPosition.y); _FPSLabel.setPosition(_FPSLabel.width / 2 + locStatsPosition.x, _FPSLabel.height / 2 + locStatsPosition.y); diff --git a/cocos2d/labels/CCLabelAtlas.js b/cocos2d/labels/CCLabelAtlas.js index 2b8c06178f..f2dd4affd9 100644 --- a/cocos2d/labels/CCLabelAtlas.js +++ b/cocos2d/labels/CCLabelAtlas.js @@ -75,10 +75,7 @@ cc.LabelAtlas = cc.AtlasNode.extend(/** @lends cc.LabelAtlas# */{ }, _createRenderCmd: function(){ - if(cc._renderType === cc.game.RENDER_TYPE_WEBGL) return new cc.LabelAtlas.WebGLRenderCmd(this); - else - return new cc.LabelAtlas.CanvasRenderCmd(this); }, /** diff --git a/cocos2d/labels/CCLabelAtlasCanvasRenderCmd.js b/cocos2d/labels/CCLabelAtlasCanvasRenderCmd.js index 890c98be25..e69de29bb2 100644 --- a/cocos2d/labels/CCLabelAtlasCanvasRenderCmd.js +++ b/cocos2d/labels/CCLabelAtlasCanvasRenderCmd.js @@ -1,110 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -(function(){ - cc.LabelAtlas.CanvasRenderCmd = function(renderableObject){ - cc.AtlasNode.CanvasRenderCmd.call(this, renderableObject); - this._needDraw = false; - }; - - var proto = cc.LabelAtlas.CanvasRenderCmd.prototype = Object.create(cc.AtlasNode.CanvasRenderCmd.prototype); - proto.constructor = cc.LabelAtlas.CanvasRenderCmd; - - proto.setCascade = function(){ - var node = this._node; - node._cascadeOpacityEnabled = true; - node._cascadeColorEnabled = false; - }; - - proto.updateAtlasValues = function(){ - var node = this._node; - var locString = node._string || ""; - var n = locString.length; - var texture = this._textureToRender; - var locItemWidth = node._itemWidth , locItemHeight = node._itemHeight; //needn't multiply cc.contentScaleFactor(), because sprite's draw will do this - - for (var i = 0, cr = -1; i < n; i++) { - var a = locString.charCodeAt(i) - node._mapStartChar.charCodeAt(0); - var row = parseInt(a % node._itemsPerRow, 10); - var col = parseInt(a / node._itemsPerRow, 10); - if(row < 0 || col < 0) - continue; - var rect = cc.rect(row * locItemWidth, col * locItemHeight, locItemWidth, locItemHeight); - var textureContent = texture._contentSize; - if(rect.x < 0 || rect.y < 0 || rect.x + rect.width > textureContent.width || rect.y + rect.height > textureContent.height) - continue; - - cr++; - var c = locString.charCodeAt(i); - var fontChar = node.getChildByTag(i); - if (!fontChar) { - fontChar = new cc.Sprite(); - if (c === 32) { - fontChar.init(); - fontChar.setTextureRect(cc.rect(0, 0, 10, 10), false, cc.size(0, 0)); - } else - fontChar.initWithTexture(texture, rect); - - cc.Node.prototype.addChild.call(node, fontChar, 0, i); - } else { - if (c === 32) { - fontChar.init(); - fontChar.setTextureRect(cc.rect(0, 0, 10, 10), false, cc.size(0, 0)); - } else { - // reusing fonts - fontChar.initWithTexture(texture, rect); - // restore to default in case they were modified - fontChar.visible = true; - } - } - fontChar.setPosition(cr * locItemWidth + locItemWidth / 2, locItemHeight / 2); - } - this.updateContentSize(i, cr+1); - }; - - proto.updateContentSize = function(i, cr){ - var node = this._node, - contentSize = node._contentSize; - if(i !== cr && i*node._itemWidth === contentSize.width && node._itemHeight === contentSize.height){ - node.setContentSize(cr * node._itemWidth, node._itemHeight); - } - }; - - proto.setString = function(label){ - var node = this._node; - if (node._children) { - var locChildren = node._children; - var len = locChildren.length; - for (var i = 0; i < len; i++) { - var child = locChildren[i]; - if (child && !child._lateChild) - child.visible = false; - } - } - }; - - proto._addChild = function(){ - child._lateChild = true; - }; -})(); \ No newline at end of file diff --git a/cocos2d/labels/CCLabelBMFont.js b/cocos2d/labels/CCLabelBMFont.js index 474eb0067a..46e386ce6f 100644 --- a/cocos2d/labels/CCLabelBMFont.js +++ b/cocos2d/labels/CCLabelBMFont.js @@ -114,10 +114,7 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ _className: "LabelBMFont", _createRenderCmd: function(){ - if(cc._renderType === cc.game.RENDER_TYPE_WEBGL) return new cc.LabelBMFont.WebGLRenderCmd(this); - else - return new cc.LabelBMFont.CanvasRenderCmd(this); }, _setString: function (newString, needUpdateLabel) { @@ -207,7 +204,8 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ }, /** - * Initialization of the node, please do not call this function by yourself, you should pass the parameters to constructor to initialize it
. + * Initialization of the node, please do not call this function by yourself, you should pass the parameters to constructor to initialize it +. */ init: function () { return this.initWithString(null, null, null, null, null); diff --git a/cocos2d/labels/CCLabelBMFontCanvasRenderCmd.js b/cocos2d/labels/CCLabelBMFontCanvasRenderCmd.js index 1d43842993..e69de29bb2 100644 --- a/cocos2d/labels/CCLabelBMFontCanvasRenderCmd.js +++ b/cocos2d/labels/CCLabelBMFontCanvasRenderCmd.js @@ -1,107 +0,0 @@ -/**************************************************************************** - 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. - - Use any of these editors to generate BMFonts: - http://glyphdesigner.71squared.com/ (Commercial, Mac OS X) - http://www.n4te.com/hiero/hiero.jnlp (Free, Java) - http://slick.cokeandcode.com/demos/hiero.jnlp (Free, Java) - http://www.angelcode.com/products/bmfont/ (Free, Windows only) - ****************************************************************************/ - -(function(){ - cc.LabelBMFont.CanvasRenderCmd = function(renderableObject){ - cc.SpriteBatchNode.CanvasRenderCmd.call(this, renderableObject); - this._needDraw = true; - }; - - var proto = cc.LabelBMFont.CanvasRenderCmd.prototype = Object.create(cc.SpriteBatchNode.CanvasRenderCmd.prototype); - proto.constructor = cc.LabelBMFont.CanvasRenderCmd; - - proto.rendering = function(){ - void 0; - }; - - proto._updateCharTexture = function(fontChar, rect, key){ - if (key === 32) { - fontChar.setTextureRect(rect, false, cc.size(0, 0)); - } else { - // updating previous sprite - fontChar.setTextureRect(rect, false); - // restore to default in case they were modified - fontChar.visible = true; - } - }; - - proto._updateCharColorAndOpacity = function(fontChar){ - // Color MUST be set before opacity, since opacity might change color if OpacityModifyRGB is on - fontChar._displayedColor = this._displayedColor; - fontChar._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty); - fontChar._displayedOpacity = this._displayedOpacity; - fontChar._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.opacityDirty); - }; - - proto.setTexture = function (texture) { - var node = this._node; - var locChildren = node._children; - var locDisplayedColor = this._displayedColor; - for (var i = 0; i < locChildren.length; i++) { - var selChild = locChildren[i]; - var cm = selChild._renderCmd; - var childDColor = cm._displayedColor; - if (this._texture !== cm._texture && (childDColor.r !== locDisplayedColor.r || - childDColor.g !== locDisplayedColor.g || childDColor.b !== locDisplayedColor.b)) - continue; - selChild.texture = texture; - } - this._texture = texture; - }; - - proto._changeTextureColor = function(){ - var node = this._node; - var texture = this._textureToRender, - contentSize = texture.getContentSize(); - - var oTexture = node._texture, - oElement = oTexture.getHtmlElementObj(); - var disColor = this._displayedColor; - var textureRect = cc.rect(0, 0, oElement.width, oElement.height); - if(texture && contentSize.width > 0){ - if(!oElement) - return; - this._textureToRender = oTexture._generateColorTexture(disColor.r, disColor.g, disColor.b, textureRect); - } - }; - - proto._updateChildrenDisplayedOpacity = function(locChild){ - cc.Node.prototype.updateDisplayedOpacity.call(locChild, this._displayedOpacity); - }; - - proto._updateChildrenDisplayedColor = function(locChild){ - cc.Node.prototype.updateDisplayedColor.call(locChild, this._displayedColor); - }; - - proto._initBatchTexture = function(){}; - -})(); \ No newline at end of file diff --git a/cocos2d/node-grid/CCNodeGrid.js b/cocos2d/node-grid/CCNodeGrid.js index f1cb9b4658..0db98eab66 100644 --- a/cocos2d/node-grid/CCNodeGrid.js +++ b/cocos2d/node-grid/CCNodeGrid.js @@ -98,7 +98,7 @@ cc.NodeGrid = cc.Node.extend({ // Update Z vertex manually //this._transform4x4.mat[14] = this._vertexZ; - t4x4Mat[14] = this._vertexZ; + t4x4Mat[14] = this._node.__z || 0; //optimize performance for Javascript topMat4.multiply(t4x4) ; // = cc.kmGLMultMatrix(this._transform4x4); @@ -123,10 +123,7 @@ cc.NodeGrid = cc.Node.extend({ }, _createRenderCmd: function(){ - if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) return new cc.NodeGrid.WebGLRenderCmd(this); - else - return new cc.Node.CanvasRenderCmd(this); // cc.NodeGrid doesn't support Canvas mode. } }); diff --git a/cocos2d/parallax/CCParallaxNode.js b/cocos2d/parallax/CCParallaxNode.js index a994709bc2..2b0a759984 100644 --- a/cocos2d/parallax/CCParallaxNode.js +++ b/cocos2d/parallax/CCParallaxNode.js @@ -232,9 +232,6 @@ cc.ParallaxNode = cc.Node.extend(/** @lends cc.ParallaxNode# */{ }, _createRenderCmd: function(){ - if(cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new cc.ParallaxNode.CanvasRenderCmd(this); - else return new cc.ParallaxNode.WebGLRenderCmd(this); } }); diff --git a/cocos2d/parallax/CCParallaxNodeRenderCmd.js b/cocos2d/parallax/CCParallaxNodeRenderCmd.js index 8a248b737e..de092928fb 100644 --- a/cocos2d/parallax/CCParallaxNodeRenderCmd.js +++ b/cocos2d/parallax/CCParallaxNodeRenderCmd.js @@ -24,25 +24,6 @@ //TODO find a way to simple these code. -(function(){ - cc.ParallaxNode.CanvasRenderCmd = function(renderable){ - cc.Node.CanvasRenderCmd.call(this, renderable); - this._needDraw = false; - }; - - var proto = cc.ParallaxNode.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype); - proto.constructor = cc.ParallaxNode.CanvasRenderCmd; - - proto.updateStatus = function(){ - this._node._updateParallaxPosition(); - cc.Node.CanvasRenderCmd.prototype.updateStatus.call(this); - }; - - proto._syncStatus = function(parentCmd){ - this._node._updateParallaxPosition(); - cc.Node.CanvasRenderCmd.prototype._syncStatus.call(this, parentCmd); - } -})(); cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { if(cc._renderType !== cc.game.RENDER_TYPE_WEBGL) diff --git a/cocos2d/particle/CCParticleBatchNode.js b/cocos2d/particle/CCParticleBatchNode.js index 1c786386fc..a61ecb2c84 100644 --- a/cocos2d/particle/CCParticleBatchNode.js +++ b/cocos2d/particle/CCParticleBatchNode.js @@ -102,9 +102,6 @@ cc.ParticleBatchNode = cc.Node.extend(/** @lends cc.ParticleBatchNode# */{ }, _createRenderCmd: function(){ - if(cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new cc.ParticleBatchNode.CanvasRenderCmd(this); - else return new cc.ParticleBatchNode.WebGLRenderCmd(this); }, diff --git a/cocos2d/particle/CCParticleBatchNodeCanvasRenderCmd.js b/cocos2d/particle/CCParticleBatchNodeCanvasRenderCmd.js index 36da185ecb..e69de29bb2 100644 --- a/cocos2d/particle/CCParticleBatchNodeCanvasRenderCmd.js +++ b/cocos2d/particle/CCParticleBatchNodeCanvasRenderCmd.js @@ -1,38 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -(function(){ - /** - * cc.ParticleBatchNode's rendering objects of Canvas - */ - cc.ParticleBatchNode.CanvasRenderCmd = function(renderable){ - cc.Node.CanvasRenderCmd.call(this, renderable); - this._needDraw = false; - }; - - var proto = cc.ParticleBatchNode.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype); - proto.constructor = cc.ParticleBatchNode.CanvasRenderCmd; - - proto._initWithTexture = function(){}; -})(); diff --git a/cocos2d/particle/CCParticleExamples.js b/cocos2d/particle/CCParticleExamples.js index 7c89bb37fc..e69de29bb2 100644 --- a/cocos2d/particle/CCParticleExamples.js +++ b/cocos2d/particle/CCParticleExamples.js @@ -1,1006 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -/** - * A fire particle system - * @class - * @extends cc.ParticleSystem - * - * @example - * var emitter = new cc.ParticleFire(); - */ -cc.ParticleFire = cc.ParticleSystem.extend(/** @lends cc.ParticleFire# */{ - /** - *

The cc.ParticleFire's constructor.
- * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleFire()".
- * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.

- */ - ctor:function () { - cc.ParticleSystem.prototype.ctor.call(this, (cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 300 : 150); - }, - - /** - * initialize a fire particle system with number Of Particles - * @param {Number} numberOfParticles - * @return {Boolean} - */ - initWithTotalParticles:function (numberOfParticles) { - if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) { - // duration - this.setDuration(cc.ParticleSystem.DURATION_INFINITY); - - // Gravity Mode - this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY); - - - // Gravity Mode: gravity - this.setGravity(cc.p(0, 0)); - - // Gravity Mode: radial acceleration - this.setRadialAccel(0); - this.setRadialAccelVar(0); - - // Gravity Mode: speed of particles - this.setSpeed(60); - this.setSpeedVar(20); - - // starting angle - this.setAngle(90); - this.setAngleVar(10); - - // emitter position - var winSize = cc.director.getWinSize(); - this.setPosition(winSize.width / 2, 60); - this.setPosVar(cc.p(40, 20)); - - // life of particles - this.setLife(3); - this.setLifeVar(0.25); - - - // size, in pixels - this.setStartSize(54.0); - this.setStartSizeVar(10.0); - this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE); - - // emits per frame - this.setEmissionRate(this.getTotalParticles() / this.getLife()); - - // color of particles - this.setStartColor(cc.color(194,64,31,255)); - this.setStartColorVar(cc.color(0,0,0,0)); - this.setEndColor(cc.color(0,0,0,255)); - this.setEndColorVar(cc.color(0,0,0,0)); - - // additive - this.setBlendAdditive(true); - return true; - } - return false; - } -}); - -/** - * Create a fire particle system - * @deprecated since v3.0 please use new cc.ParticleFire() instead - * @return {cc.ParticleFire} - */ -cc.ParticleFire.create = function () { - return new cc.ParticleFire(); -}; - -/** - * A fireworks particle system - * @class - * @extends cc.ParticleSystem - * - * @example - * var emitter = new cc.ParticleFireworks(); - */ -cc.ParticleFireworks = cc.ParticleSystem.extend(/** @lends cc.ParticleFireworks# */{ - /** - *

The cc.ParticleFireworks's constructor.
- * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleFireworks()".
- * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.

- */ - ctor:function () { - cc.ParticleSystem.prototype.ctor.call(this, (cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 1500 : 150); - }, - - /** - * initialize a fireworks particle system with number Of Particles - * @param {Number} numberOfParticles - * @return {Boolean} - */ - initWithTotalParticles:function (numberOfParticles) { - if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) { - // duration - this.setDuration(cc.ParticleSystem.DURATION_INFINITY); - - // Gravity Mode - this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY); - - // Gravity Mode: gravity - this.setGravity(cc.p(0, -90)); - - // Gravity Mode: radial - this.setRadialAccel(0); - this.setRadialAccelVar(0); - - // Gravity Mode: speed of particles - this.setSpeed(180); - this.setSpeedVar(50); - - // emitter position - var winSize = cc.director.getWinSize(); - this.setPosition(winSize.width / 2, winSize.height / 2); - - // angle - this.setAngle(90); - this.setAngleVar(20); - - // life of particles - this.setLife(3.5); - this.setLifeVar(1); - - // emits per frame - this.setEmissionRate(this.getTotalParticles() / this.getLife()); - - // color of particles - this.setStartColor(cc.color(128,128,128,255)); - this.setStartColorVar(cc.color(128,128,128,255)); - this.setEndColor(cc.color(26,26,26,51)); - this.setEndColorVar(cc.color(26,26,26,51)); - - // size, in pixels - this.setStartSize(8.0); - this.setStartSizeVar(2.0); - this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE); - - // additive - this.setBlendAdditive(false); - return true; - } - return false; - } -}); - -/** - * Create a fireworks particle system - * @deprecated since v3.0 please use new cc.ParticleFireworks() instead. - * @return {cc.ParticleFireworks} - */ -cc.ParticleFireworks.create = function () { - return new cc.ParticleFireworks(); -}; - -/** - * A sun particle system - * @class - * @extends cc.ParticleSystem - * - * @example - * var emitter = new cc.ParticleSun(); - */ -cc.ParticleSun = cc.ParticleSystem.extend(/** @lends cc.ParticleSun# */{ - /** - *

The cc.ParticleSun's constructor.
- * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleSun()".
- * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.

- */ - ctor:function () { - cc.ParticleSystem.prototype.ctor.call(this, (cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 350 : 150); - }, - - /** - * initialize a sun particle system with number Of Particles - * @param {Number} numberOfParticles - * @return {Boolean} - */ - initWithTotalParticles:function (numberOfParticles) { - if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) { - // additive - this.setBlendAdditive(true); - - // duration - this.setDuration(cc.ParticleSystem.DURATION_INFINITY); - - // Gravity Mode - this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY); - - // Gravity Mode: gravity - this.setGravity(cc.p(0, 0)); - - // Gravity mode: radial acceleration - this.setRadialAccel(0); - this.setRadialAccelVar(0); - - // Gravity mode: speed of particles - this.setSpeed(20); - this.setSpeedVar(5); - - // angle - this.setAngle(90); - this.setAngleVar(360); - - // emitter position - var winSize = cc.director.getWinSize(); - this.setPosition(winSize.width / 2, winSize.height / 2); - this.setPosVar(cc.p(0,0)); - - // life of particles - this.setLife(1); - this.setLifeVar(0.5); - - // size, in pixels - this.setStartSize(30.0); - this.setStartSizeVar(10.0); - this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE); - - // emits per seconds - this.setEmissionRate(this.getTotalParticles() / this.getLife()); - - // color of particles - this.setStartColor(cc.color(194, 64, 31, 255)); - this.setStartColorVar(cc.color(0, 0, 0, 0)); - this.setEndColor(cc.color(0, 0, 0, 255)); - this.setEndColorVar(cc.color(0, 0, 0, 0)); - - return true; - } - return false; - } -}); - -/** - * Create a sun particle system - * @deprecated since v3.0 please use new cc.ParticleSun() instead. - * @return {cc.ParticleSun} - */ -cc.ParticleSun.create = function () { - return new cc.ParticleSun(); -}; - -//! @brief A particle system -/** - * A galaxy particle system - * @class - * @extends cc.ParticleSystem - * - * @example - * var emitter = new cc.ParticleGalaxy(); - */ -cc.ParticleGalaxy = cc.ParticleSystem.extend(/** @lends cc.ParticleGalaxy# */{ - /** - *

The cc.ParticleGalaxy's constructor.
- * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleGalaxy()".
- * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.

- */ - ctor:function () { - cc.ParticleSystem.prototype.ctor.call(this, (cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 200 : 100); - }, - - /** - * initialize a galaxy particle system with number Of Particles - * @param {Number} numberOfParticles - * @return {Boolean} - */ - initWithTotalParticles:function (numberOfParticles) { - if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) { - // duration - this.setDuration(cc.ParticleSystem.DURATION_INFINITY); - - // Gravity Mode - this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY); - - // Gravity Mode: gravity - this.setGravity(cc.p(0, 0)); - - // Gravity Mode: speed of particles - this.setSpeed(60); - this.setSpeedVar(10); - - // Gravity Mode: radial - this.setRadialAccel(-80); - this.setRadialAccelVar(0); - - // Gravity Mode: tangential - this.setTangentialAccel(80); - this.setTangentialAccelVar(0); - - // angle - this.setAngle(90); - this.setAngleVar(360); - - // emitter position - var winSize = cc.director.getWinSize(); - this.setPosition(winSize.width / 2, winSize.height / 2); - this.setPosVar(cc.p(0,0)); - - // life of particles - this.setLife(4); - this.setLifeVar(1); - - // size, in pixels - this.setStartSize(37.0); - this.setStartSizeVar(10.0); - this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE); - - // emits per second - this.setEmissionRate(this.getTotalParticles() / this.getLife()); - - // color of particles - this.setStartColor(cc.color(31, 64, 194, 255)); - this.setStartColorVar(cc.color(0, 0, 0, 0)); - this.setEndColor(cc.color(0, 0, 0, 255)); - this.setEndColorVar(cc.color(0, 0, 0, 0)); - - // additive - this.setBlendAdditive(true); - return true; - } - return false; - } -}); -/** - * Create a galaxy particle system - * @deprecated since v3.0 please use new cc.OarticleGalaxy() instead. - * @return {cc.ParticleGalaxy} - */ -cc.ParticleGalaxy.create = function () { - return new cc.ParticleGalaxy(); -}; - -/** - * A flower particle system - * @class - * @extends cc.ParticleSystem - * - * @example - * var emitter = new cc.ParticleFlower(); - */ -cc.ParticleFlower = cc.ParticleSystem.extend(/** @lends cc.ParticleFlower# */{ - /** - *

The cc.ParticleFlower's constructor.
- * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleFlower()".
- * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.

- */ - ctor : function () { - cc.ParticleSystem.prototype.ctor.call(this, (cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 250 : 100); - }, - - /** - * initialize a flower particle system with number Of Particles - * @param {Number} numberOfParticles - * @return {Boolean} - */ - initWithTotalParticles:function (numberOfParticles) { - if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) { - // duration - this.setDuration(cc.ParticleSystem.DURATION_INFINITY); - - // Gravity Mode - this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY); - - // Gravity Mode: gravity - this.setGravity(cc.p(0, 0)); - - // Gravity Mode: speed of particles - this.setSpeed(80); - this.setSpeedVar(10); - - // Gravity Mode: radial - this.setRadialAccel(-60); - this.setRadialAccelVar(0); - - // Gravity Mode: tangential - this.setTangentialAccel(15); - this.setTangentialAccelVar(0); - - // angle - this.setAngle(90); - this.setAngleVar(360); - - // emitter position - var winSize = cc.director.getWinSize(); - this.setPosition(winSize.width / 2, winSize.height / 2); - this.setPosVar(cc.p(0,0)); - - // life of particles - this.setLife(4); - this.setLifeVar(1); - - // size, in pixels - this.setStartSize(30.0); - this.setStartSizeVar(10.0); - this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE); - - // emits per second - this.setEmissionRate(this.getTotalParticles() / this.getLife()); - - // color of particles - this.setStartColor(cc.color(128, 128, 128, 255)); - this.setStartColorVar(cc.color(128, 128, 128, 128)); - this.setEndColor(cc.color(0, 0, 0, 255)); - this.setEndColorVar(cc.color(0, 0, 0, 0)); - - // additive - this.setBlendAdditive(true); - return true; - } - return false; - } -}); - -/** - * Create a flower particle system - * @deprecated since v3.0 please use new cc.ParticleFlower() instead. - * @return {cc.ParticleFlower} - */ -cc.ParticleFlower.create = function () { - return new cc.ParticleFlower(); -}; - -//! @brief A meteor particle system -/** - * A meteor particle system - * @class - * @extends cc.ParticleSystem - * - * @example - * var emitter = new cc.ParticleMeteor(); - */ -cc.ParticleMeteor = cc.ParticleSystem.extend(/** @lends cc.ParticleMeteor# */{ - /** - *

The cc.ParticleMeteor's constructor.
- * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleMeteor()".
- * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.

- */ - ctor:function () { - cc.ParticleSystem.prototype.ctor.call(this, (cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 150 : 100); - }, - - /** - * initialize a meteor particle system with number Of Particles - * @param {Number} numberOfParticles - * @return {Boolean} - */ - initWithTotalParticles:function (numberOfParticles) { - if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) { - // duration - this.setDuration(cc.ParticleSystem.DURATION_INFINITY); - - // Gravity Mode - this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY); - - // Gravity Mode: gravity - this.setGravity(cc.p(-200, 200)); - - // Gravity Mode: speed of particles - this.setSpeed(15); - this.setSpeedVar(5); - - // Gravity Mode: radial - this.setRadialAccel(0); - this.setRadialAccelVar(0); - - // Gravity Mode: tangential - this.setTangentialAccel(0); - this.setTangentialAccelVar(0); - - // angle - this.setAngle(90); - this.setAngleVar(360); - - // emitter position - var winSize = cc.director.getWinSize(); - this.setPosition(winSize.width / 2, winSize.height / 2); - this.setPosVar(cc.p(0,0)); - - // life of particles - this.setLife(2); - this.setLifeVar(1); - - // size, in pixels - this.setStartSize(60.0); - this.setStartSizeVar(10.0); - this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE); - - // emits per second - this.setEmissionRate(this.getTotalParticles() / this.getLife()); - - // color of particles - this.setStartColor(cc.color(51, 102, 179)); - this.setStartColorVar(cc.color(0, 0, 51, 26)); - this.setEndColor(cc.color(0, 0, 0, 255)); - this.setEndColorVar(cc.color(0, 0, 0, 0)); - - // additive - this.setBlendAdditive(true); - return true; - } - return false; - } -}); - -/** - * Create a meteor particle system - * @deprecated since v3.0 please use new cc.ParticleMeteor() instead. - * @return {cc.ParticleMeteor} - */ -cc.ParticleMeteor.create = function () { - return new cc.ParticleMeteor(); -}; - -/** - * A spiral particle system - * @class - * @extends cc.ParticleSystem - * - * @example - * var emitter = new cc.ParticleSpiral(); - */ -cc.ParticleSpiral = cc.ParticleSystem.extend(/** @lends cc.ParticleSpiral# */{ - - /** - *

The cc.ParticleSpiral's constructor.
- * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleSpiral()".
- * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.

- */ - ctor:function() { - cc.ParticleSystem.prototype.ctor.call(this,(cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 500 : 100); - }, - - /** - * initialize a spiral particle system with number Of Particles - * @param {Number} numberOfParticles - * @return {Boolean} - */ - initWithTotalParticles:function (numberOfParticles) { - if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) { - // duration - this.setDuration(cc.ParticleSystem.DURATION_INFINITY); - - // Gravity Mode - this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY); - - // Gravity Mode: gravity - this.setGravity(cc.p(0, 0)); - - // Gravity Mode: speed of particles - this.setSpeed(150); - this.setSpeedVar(0); - - // Gravity Mode: radial - this.setRadialAccel(-380); - this.setRadialAccelVar(0); - - // Gravity Mode: tangential - this.setTangentialAccel(45); - this.setTangentialAccelVar(0); - - // angle - this.setAngle(90); - this.setAngleVar(0); - - // emitter position - var winSize = cc.director.getWinSize(); - this.setPosition(winSize.width / 2, winSize.height / 2); - this.setPosVar(cc.p(0,0)); - - // life of particles - this.setLife(12); - this.setLifeVar(0); - - // size, in pixels - this.setStartSize(20.0); - this.setStartSizeVar(0.0); - this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE); - - // emits per second - this.setEmissionRate(this.getTotalParticles() / this.getLife()); - - // color of particles - this.setStartColor(cc.color(128,128,128,255)); - this.setStartColorVar(cc.color(128,128,128,0)); - this.setEndColor(cc.color(128,128,128,255)); - this.setEndColorVar(cc.color(128,128,128,0)); - - // additive - this.setBlendAdditive(false); - return true; - } - return false; - } -}); - -/** - * Create a spiral particle system - * @deprecated since v3.0 please use new cc.ParticleSpiral() instead. - * @return {cc.ParticleSpiral} - */ -cc.ParticleSpiral.create = function () { - return new cc.ParticleSpiral(); -}; - -/** - * An explosion particle system - * @class - * @extends cc.ParticleSystem - * - * @example - * var emitter = new cc.ParticleExplosion(); - */ -cc.ParticleExplosion = cc.ParticleSystem.extend(/** @lends cc.ParticleExplosion# */{ - /** - *

The cc.ParticleExplosion's constructor.
- * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleExplosion()".
- * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.

- */ - ctor:function () { - cc.ParticleSystem.prototype.ctor.call(this, (cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 700 : 300); - }, - - /** - * initialize an explosion particle system with number Of Particles - * @param {Number} numberOfParticles - * @return {Boolean} - */ - initWithTotalParticles:function (numberOfParticles) { - if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) { - // duration - this.setDuration(0.1); - - this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY); - - // Gravity Mode: gravity - this.setGravity(cc.p(0, 0)); - - // Gravity Mode: speed of particles - this.setSpeed(70); - this.setSpeedVar(40); - - // Gravity Mode: radial - this.setRadialAccel(0); - this.setRadialAccelVar(0); - - // Gravity Mode: tangential - this.setTangentialAccel(0); - this.setTangentialAccelVar(0); - - // angle - this.setAngle(90); - this.setAngleVar(360); - - // emitter position - var winSize = cc.director.getWinSize(); - this.setPosition(winSize.width / 2, winSize.height / 2); - this.setPosVar(cc.p(0,0)); - - // life of particles - this.setLife(5.0); - this.setLifeVar(2); - - // size, in pixels - this.setStartSize(15.0); - this.setStartSizeVar(10.0); - this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE); - - // emits per second - this.setEmissionRate(this.getTotalParticles() / this.getDuration()); - - // color of particles - this.setStartColor(cc.color(179, 26, 51, 255)); - this.setStartColorVar(cc.color(128, 128, 128, 0)); - this.setEndColor(cc.color(128, 128, 128, 0)); - this.setEndColorVar(cc.color(128, 128, 128, 0)); - - // additive - this.setBlendAdditive(false); - return true; - } - return false; - } -}); - -/** - * Create an explosion particle system - * @deprecated since v3.0 please use new cc.ParticleExplosion() instead. - * @return {cc.ParticleExplosion} - */ -cc.ParticleExplosion.create = function () { - return new cc.ParticleExplosion(); -}; - -/** - * A smoke particle system - * @class - * @extends cc.ParticleSystem - * - * @example - * var emitter = new cc.ParticleSmoke(); - */ -cc.ParticleSmoke = cc.ParticleSystem.extend(/** @lends cc.ParticleSmoke# */{ - - /** - *

The cc.ParticleSmoke's constructor.
- * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleSmoke()".
- * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.

- */ - ctor:function () { - cc.ParticleSystem.prototype.ctor.call(this, (cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 200 : 100); - }, - - /** - * initialize a smoke particle system with number Of Particles - * @param {Number} numberOfParticles - * @return {Boolean} - */ - initWithTotalParticles:function (numberOfParticles) { - if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) { - // duration - this.setDuration(cc.ParticleSystem.DURATION_INFINITY); - - // Emitter mode: Gravity Mode - this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY); - - // Gravity Mode: gravity - this.setGravity(cc.p(0, 0)); - - // Gravity Mode: radial acceleration - this.setRadialAccel(0); - this.setRadialAccelVar(0); - - // Gravity Mode: speed of particles - this.setSpeed(25); - this.setSpeedVar(10); - - // angle - this.setAngle(90); - this.setAngleVar(5); - - // emitter position - var winSize = cc.director.getWinSize(); - this.setPosition(winSize.width / 2, 0); - this.setPosVar(cc.p(20, 0)); - - // life of particles - this.setLife(4); - this.setLifeVar(1); - - // size, in pixels - this.setStartSize(60.0); - this.setStartSizeVar(10.0); - this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE); - - // emits per frame - this.setEmissionRate(this.getTotalParticles() / this.getLife()); - - // color of particles - this.setStartColor(cc.color(204, 204, 204, 255)); - this.setStartColorVar(cc.color(5, 5, 5, 0)); - this.setEndColor(cc.color(0, 0, 0, 255)); - this.setEndColorVar(cc.color(0, 0, 0, 0)); - - // additive - this.setBlendAdditive(false); - return true; - } - return false; - } -}); - -/** - * Create a smoke particle system - * @deprecated since v3.0 please use new cc.ParticleSmoke() instead. - * @return {cc.ParticleSmoke} - */ -cc.ParticleSmoke.create = function () { - return new cc.ParticleSmoke(); -}; - -/** - * A snow particle system - * @class - * @extends cc.ParticleSystem - * - * @example - * var emitter = new cc.ParticleSnow(); - */ -cc.ParticleSnow = cc.ParticleSystem.extend(/** @lends cc.ParticleSnow# */{ - - /** - *

The cc.ParticleSnow's constructor.
- * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleSnow()".
- * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.

- */ - ctor:function () { - cc.ParticleSystem.prototype.ctor.call(this, (cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 700 : 250); - }, - - /** - * initialize a snow particle system with number Of Particles - * @param {Number} numberOfParticles - * @return {Boolean} - */ - initWithTotalParticles:function (numberOfParticles) { - if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) { - // duration - this.setDuration(cc.ParticleSystem.DURATION_INFINITY); - - // set gravity mode. - this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY); - - // Gravity Mode: gravity - this.setGravity(cc.p(0, -1)); - - // Gravity Mode: speed of particles - this.setSpeed(5); - this.setSpeedVar(1); - - // Gravity Mode: radial - this.setRadialAccel(0); - this.setRadialAccelVar(1); - - // Gravity mode: tangential - this.setTangentialAccel(0); - this.setTangentialAccelVar(1); - - // emitter position - var winSize = cc.director.getWinSize(); - this.setPosition(winSize.width / 2, winSize.height + 10); - this.setPosVar(cc.p(winSize.width / 2, 0)); - - // angle - this.setAngle(-90); - this.setAngleVar(5); - - // life of particles - this.setLife(45); - this.setLifeVar(15); - - // size, in pixels - this.setStartSize(10.0); - this.setStartSizeVar(5.0); - this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE); - - // emits per second - this.setEmissionRate(10); - - // color of particles - this.setStartColor(cc.color(255, 255, 255, 255)); - this.setStartColorVar(cc.color(0, 0, 0, 0)); - this.setEndColor(cc.color(255, 255, 255, 0)); - this.setEndColorVar(cc.color(0, 0, 0, 0)); - - // additive - this.setBlendAdditive(false); - return true; - } - return false; - } -}); - -/** - * Create a snow particle system - * @deprecated since v3.0 please use new cc.ParticleSnow() instead. - * @return {cc.ParticleSnow} - */ -cc.ParticleSnow.create = function () { - return new cc.ParticleSnow(); -}; - -//! @brief A rain particle system -/** - * A rain particle system - * @class - * @extends cc.ParticleSystem - * - * @example - * var emitter = new cc.ParticleRain(); - */ -cc.ParticleRain = cc.ParticleSystem.extend(/** @lends cc.ParticleRain# */{ - - /** - *

The cc.ParticleRain's constructor.
- * This function will automatically be invoked when you create a node using new construction: "var node = new cc.ParticleRain()".
- * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.

- */ - ctor:function () { - cc.ParticleSystem.prototype.ctor.call(this, (cc._renderType === cc.game.RENDER_TYPE_WEBGL) ? 1000 : 300); - }, - - /** - * initialize a rain particle system with number Of Particles - * @param {Number} numberOfParticles - * @return {Boolean} - */ - initWithTotalParticles:function (numberOfParticles) { - if (cc.ParticleSystem.prototype.initWithTotalParticles.call(this, numberOfParticles)) { - // duration - this.setDuration(cc.ParticleSystem.DURATION_INFINITY); - - this.setEmitterMode(cc.ParticleSystem.MODE_GRAVITY); - - // Gravity Mode: gravity - this.setGravity(cc.p(10, -10)); - - // Gravity Mode: radial - this.setRadialAccel(0); - this.setRadialAccelVar(1); - - // Gravity Mode: tangential - this.setTangentialAccel(0); - this.setTangentialAccelVar(1); - - // Gravity Mode: speed of particles - this.setSpeed(130); - this.setSpeedVar(30); - - // angle - this.setAngle(-90); - this.setAngleVar(5); - - - // emitter position - var winSize = cc.director.getWinSize(); - this.setPosition(winSize.width / 2, winSize.height); - this.setPosVar(cc.p(winSize.width / 2, 0)); - - // life of particles - this.setLife(4.5); - this.setLifeVar(0); - - // size, in pixels - this.setStartSize(4.0); - this.setStartSizeVar(2.0); - this.setEndSize(cc.ParticleSystem.START_SIZE_EQUAL_TO_END_SIZE); - - // emits per second - this.setEmissionRate(20); - - // color of particles - this.setStartColor(cc.color(179, 204, 255, 255)); - this.setStartColorVar(cc.color(0, 0, 0, 0)); - this.setEndColor(cc.color(179, 204, 255, 128)); - this.setEndColorVar(cc.color(0, 0, 0, 0)); - - // additive - this.setBlendAdditive(false); - return true; - } - return false; - } -}); - -/** - * Create a rain particle system - * @deprecated since v3.0 please use cc.ParticleRain() instead. - * @return {cc.ParticleRain} - */ -cc.ParticleRain.create = function () { - return new cc.ParticleRain(); -}; diff --git a/cocos2d/particle/CCParticleSystem.js b/cocos2d/particle/CCParticleSystem.js index f12686d03d..f1658f1928 100644 --- a/cocos2d/particle/CCParticleSystem.js +++ b/cocos2d/particle/CCParticleSystem.js @@ -349,9 +349,6 @@ cc.ParticleSystem = cc.Node.extend(/** @lends cc.ParticleSystem# */{ }, _createRenderCmd: function(){ - if(cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new cc.ParticleSystem.CanvasRenderCmd(this); - else return new cc.ParticleSystem.WebGLRenderCmd(this); }, @@ -1118,14 +1115,24 @@ cc.ParticleSystem = cc.Node.extend(/** @lends cc.ParticleSystem# */{ setTexture:function (texture) { if(!texture) return; + + if(typeof texture ==="string" && texture.charAt(0) === "#") + { + var frame = cc.spriteFrameCache.getSpriteFrame(texture.substr(1, texture.length -1)); + if(frame) + { + var rect = frame.getRect(); + var texture = frame.getTexture(); + } + } if(texture.isLoaded()){ - this.setTextureWithRect(texture, cc.rect(0, 0, texture.width, texture.height)); + this.setTextureWithRect(texture, rect || cc.rect(0, 0, texture.width, texture.height)); } else { this._textureLoaded = false; texture.addEventListener("load", function(sender){ this._textureLoaded = true; - this.setTextureWithRect(sender, cc.rect(0, 0, sender.width, sender.height)); + this.setTextureWithRect(sender, rect || cc.rect(0, 0, sender.width, sender.height)); }, this); } }, @@ -1422,8 +1429,16 @@ cc.ParticleSystem = cc.Node.extend(/** @lends cc.ParticleSystem# */{ // texture // Try to get the texture from the cache var textureName = locValueForKey("textureFileName", dictionary); - var imgPath = cc.path.changeBasename(this._plistFile, textureName); + if(textureName.charAt(0) === "#") + var imgPath = textureName; + else + var imgPath = cc.path.changeBasename(this._plistFile, textureName); + var tex = cc.textureCache.getTextureForKey(imgPath); + if(!tex && imgPath.charAt(0) === "#") + { + tex = imgPath; + } if (tex) { this.setTexture(tex); diff --git a/cocos2d/particle/CCParticleSystemCanvasRenderCmd.js b/cocos2d/particle/CCParticleSystemCanvasRenderCmd.js index de78252346..e69de29bb2 100644 --- a/cocos2d/particle/CCParticleSystemCanvasRenderCmd.js +++ b/cocos2d/particle/CCParticleSystemCanvasRenderCmd.js @@ -1,199 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -/** - * ParticleSystem's canvas render command - */ -(function(){ - cc.ParticleSystem.CanvasRenderCmd = function(renderable){ - cc.Node.CanvasRenderCmd.call(this, renderable); - this._needDraw = true; - - this._drawMode = cc.ParticleSystem.TEXTURE_MODE; - this._shapeType = cc.ParticleSystem.BALL_SHAPE; - - this._pointRect = cc.rect(0, 0, 0, 0); - this._tintCache = document.createElement("canvas"); - }; - var proto = cc.ParticleSystem.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype); - proto.constructor = cc.ParticleSystem.CanvasRenderCmd; - - proto.getDrawMode = function(){ - return this._drawMode; - }; - - proto.setDrawMode = function(drawMode){ - this._drawMode = drawMode; - }; - - proto.getShapeType = function(){ - return this._shapeType; - }; - - proto.setShapeType = function(shapeType){ - this._shapeType = shapeType; - }; - - proto.setBatchNode = function(batchNode){ - if (this._batchNode !== batchNode) { - this._node._batchNode = batchNode; - } - }; - - proto.updateQuadWithParticle = function (particle, newPosition) { - //do nothing - }; - - proto.updateParticlePosition = function(particle, position){ - cc.pIn(particle.drawPos, position); - }; - - proto.rendering = function (ctx, scaleX, scaleY) { - //TODO: need refactor rendering for performance - var wrapper = ctx || cc._renderContext, context = wrapper.getContext(), - node = this._node, pointRect = this._pointRect; - - wrapper.setTransform(this._worldTransform, scaleX, scaleY); - wrapper.save(); - if (node.isBlendAdditive()) - context.globalCompositeOperation = 'lighter'; - else - context.globalCompositeOperation = 'source-over'; - - var i, particle, lpx, alpha; - var particleCount = this._node.particleCount, particles = this._node._particles; - if (node.drawMode !== cc.ParticleSystem.SHAPE_MODE && node._texture) { - // Delay drawing until the texture is fully loaded by the browser - if (!node._texture._textureLoaded) { - wrapper.restore(); - return; - } - var element = node._texture.getHtmlElementObj(); - if (!element.width || !element.height) { - wrapper.restore(); - return; - } - - var drawElement = element; - for (i = 0; i < particleCount; i++) { - particle = particles[i]; - lpx = (0 | (particle.size * 0.5)); - - alpha = particle.color.a / 255; - if (alpha === 0) continue; - context.globalAlpha = alpha; - - context.save(); - context.translate((0 | particle.drawPos.x), -(0 | particle.drawPos.y)); - - var size = Math.floor(particle.size / 4) * 4; - var w = pointRect.width; - var h = pointRect.height; - - context.scale(Math.max((1 / w) * size, 0.000001), Math.max((1 / h) * size, 0.000001)); - if (particle.rotation) - context.rotate(cc.degreesToRadians(particle.rotation)); - - drawElement = particle.isChangeColor ? this._changeTextureColor(node._texture, particle.color, this._pointRect) : element; - context.drawImage(drawElement, -(0 | (w / 2)), -(0 | (h / 2))); - context.restore(); - } - } else { - var drawTool = cc._drawingUtil; - for (i = 0; i < particleCount; i++) { - particle = particles[i]; - lpx = (0 | (particle.size * 0.5)); - alpha = particle.color.a / 255; - if (alpha === 0) continue; - context.globalAlpha = alpha; - - context.save(); - context.translate(0 | particle.drawPos.x, -(0 | particle.drawPos.y)); - if (node.shapeType === cc.ParticleSystem.STAR_SHAPE) { - if (particle.rotation) - context.rotate(cc.degreesToRadians(particle.rotation)); - drawTool.drawStar(wrapper, lpx, particle.color); - } else - drawTool.drawColorBall(wrapper, lpx, particle.color); - context.restore(); - } - } - wrapper.restore(); - cc.g_NumberOfDraws++; - }; - - proto._changeTextureColor = function(texture, color, rect){ - var tintCache = this._tintCache; - var textureContentSize = texture.getContentSize(); - tintCache.width = textureContentSize.width; - tintCache.height = textureContentSize.height; - return texture._generateColorTexture(color.r, color.g, color.b, rect, tintCache); - }; - - proto.initTexCoordsWithRect = function(pointRect){ - this._pointRect = pointRect; - }; - - proto.setTotalParticles = function(tp){ - //cc.assert(tp <= this._allocatedParticles, "Particle: resizing particle array only supported for quads"); - this._node._totalParticles = (tp < 200) ? tp : 200; - }; - - proto.addParticle = function(){ - var node = this._node, - particles = node._particles, - particle; - if (node.particleCount < particles.length) { - particle = particles[node.particleCount]; - } else { - particle = new cc.Particle(); - particles.push(particle); - } - return particle; - }; - - proto._setupVBO = function(){}; - proto._allocMemory = function(){ - return true; - }; - - proto.postStep = function(){}; - - proto._setBlendAdditive = function(){ - var locBlendFunc = this._node._blendFunc; - locBlendFunc.src = cc.BLEND_SRC; - locBlendFunc.dst = cc.BLEND_DST; - }; - - proto._initWithTotalParticles = function(totalParticles){}; - 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; - } - }; -})(); diff --git a/cocos2d/physics/CCPhysicsDebugNode.js b/cocos2d/physics/CCPhysicsDebugNode.js index 003bfe3f74..e69de29bb2 100644 --- a/cocos2d/physics/CCPhysicsDebugNode.js +++ b/cocos2d/physics/CCPhysicsDebugNode.js @@ -1,212 +0,0 @@ -/**************************************************************************** - Copyright (c) 2008-2010 Ricardo Quesada - Copyright (c) 2011-2012 cocos2d-x.org - Copyright (c) 2013-2014 Chukong Technologies Inc. - Copyright (c) 2012 Scott Lembcke and Howling Moon Software - - 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. - ****************************************************************************/ - -/* - IMPORTANT - READ ME! - - This file sets pokes around in the private API a lot to provide efficient - debug rendering given nothing more than reference to a Chipmunk space. - It is not recommended to write rendering code like this in your own games - as the private API may change with little or no warning. - */ - -/** - * Converts an array of numbers into an array of vectors(x,y) - * @function - * @param {Array} verts - * @return {Array} - */ -cc.__convertVerts = function (verts) { - var ret = []; - for (var i = 0; i < verts.length / 2; i++) { - ret[i] = {x:verts[i * 2], y:verts[i * 2 + 1]}; - } - return ret; -}; - -/** - * color for body - * @function - * @param {cp.Body} body - * @return {cc.color} - */ -cc.ColorForBody = function (body) { - if (body.isRogue() || body.isSleeping()) { - return cc.color(128, 128, 128, 128); - } else if (body.nodeIdleTime > body.space.sleepTimeThreshold) { - return cc.color(84, 84, 84, 128); - } else { - return cc.color(255, 0, 0, 128); - } -}; - -/** - * draw shape - * @param {cp.Shape} shape - * @param renderer - */ -cc.DrawShape = function (shape, renderer) { - var body = shape.body; - var color = cc.ColorForBody(body); - switch (shape.collisionCode) { - case cp.CircleShape.prototype.collisionCode: - this.drawDot(shape.tc, Math.max(shape.r, 1.0), color); - this.drawSegment(shape.tc, cp.v.add(shape.tc, cp.v.mult(body.rot, shape.r)), 1.0, color); - break; - case cp.SegmentShape.prototype.collisionCode: - this.drawSegment(shape.ta, shape.tb, Math.max(shape.r, 2.0), color); - break; - case cp.PolyShape.prototype.collisionCode: - var line = cc.color(color.r, color.g, color.b, cc.lerp(color.a, 255, 0.5)); - this.drawPoly(cc.__convertVerts(shape.tVerts), color, 1.0, line); - break; - default: - cc.log("cc.DrawShape(): Bad assertion in DrawShape()"); - break; - } -}; - -/** - * draw constraint - * @param {cp.Constraint} constraint - * @param renderer - */ -cc.DrawConstraint = function (constraint, renderer) { - var body_a = constraint.a; - var body_b = constraint.b; - var a, b; - - if (constraint instanceof cp.PinJoint) { - a = body_a.local2World(constraint.anchr1); - b = body_b.local2World(constraint.anchr2); - this.drawDot(a, 3.0, cc.CONSTRAINT_COLOR); - this.drawDot(b, 3.0, cc.CONSTRAINT_COLOR); - this.drawSegment(a, b, 1.0, cc.CONSTRAINT_COLOR); - } else if (constraint instanceof cp.SlideJoint) { - a = body_a.local2World(constraint.anchr1); - b = body_b.local2World(constraint.anchr2); - - this.drawDot(a, 3.0, cc.CONSTRAINT_COLOR); - this.drawDot(b, 3.0, cc.CONSTRAINT_COLOR); - this.drawSegment(a, b, 1.0, cc.CONSTRAINT_COLOR); - } else if (constraint instanceof cp.PivotJoint) { - a = body_a.local2World(constraint.anchr1); - b = body_b.local2World(constraint.anchr2); - this.drawDot(a, 3.0, cc.CONSTRAINT_COLOR); - this.drawDot(b, 3.0, cc.CONSTRAINT_COLOR); - } else if (constraint instanceof cp.GrooveJoint) { - a = body_a.local2World(constraint.grv_a); - b = body_a.local2World(constraint.grv_b); - var c = body_b.local2World(constraint.anchr2); - - this.drawDot(c, 3.0, cc.CONSTRAINT_COLOR); - this.drawSegment(a, b, 1.0, cc.CONSTRAINT_COLOR); - } else if (constraint instanceof cp.DampedSpring) { - // TODO - } else { - //printf("Cannot draw constraint\n"); - } -}; - -/** - * @constant - * @type {cc.color} - */ -cc.CONSTRAINT_COLOR = cc.color(0, 255, 0, 128); - - -/** - *

A Node that draws the components of a physics engine.
- * Supported physics engines:
- * - Chipmunk
- * - Objective-Chipmunk

- * - * @class - * @extends cc.DrawNode - * - * @property {cp.Space} space Physic world space - */ -cc.PhysicsDebugNode = cc.DrawNode.extend({ - _space:null, - _className:"PhysicsDebugNode", - - /** - * constructor of cc.PhysicsDebugNode - * @param {cp.Space} space - */ - ctor: function (space) { - cc.DrawNode.prototype.ctor.call(this); - this._space = space; - }, - - /** - * get space - * @returns {cp.Space} - */ - getSpace:function () { - return this._space; - }, - - /** - * set space - * @param {cp.Space} space - */ - setSpace:function (space) { - this._space = space; - }, - - /** - * draw - * @param {object} context - */ - draw:function (context) { - if (!this._space) - return; - - this._space.eachShape(cc.DrawShape.bind(this)); - this._space.eachConstraint(cc.DrawConstraint.bind(this)); - cc.DrawNode.prototype.draw.call(this); - this.clear(); - }, - - _createRenderCmd: function(){ - if(cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new cc.PhysicsDebugNode.CanvasRenderCmd(this); - else - return new cc.PhysicsDebugNode.WebGLRenderCmd(this); - } -}); - -/** - * Create a debug node for a regular Chipmunk space. - * @deprecated since v3.0, please use new cc.PhysicsDebugNode(space) - * @param {cp.Space} space - * @return {cc.PhysicsDebugNode} - */ -cc.PhysicsDebugNode.create = function (space) { - return new cc.PhysicsDebugNode(space); -}; diff --git a/cocos2d/physics/CCPhysicsDebugNodeCanvasRenderCmd.js b/cocos2d/physics/CCPhysicsDebugNodeCanvasRenderCmd.js index be1f6f14ba..e69de29bb2 100644 --- a/cocos2d/physics/CCPhysicsDebugNodeCanvasRenderCmd.js +++ b/cocos2d/physics/CCPhysicsDebugNodeCanvasRenderCmd.js @@ -1,52 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -/** - * cc.PhysicsDebugNode's rendering objects of Canvas - */ -(function(){ - cc.PhysicsDebugNode.CanvasRenderCmd = function(renderableObject){ - cc.Node.CanvasRenderCmd.call(this, renderableObject); - this._buffer = renderableObject._buffer; - this._needDraw = true; - }; - - var proto = cc.PhysicsDebugNode.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype); - proto.constructor = cc.PhysicsDebugNode.CanvasRenderCmd; - - proto.rendering = function(ctx, scaleX, scaleY){ - var node = this._node; - if (!node._space) - return; - node._space.eachShape(cc.DrawShape.bind(node)); - node._space.eachConstraint(cc.DrawConstraint.bind(node)); - cc.DrawNode.CanvasRenderCmd.prototype.rendering.call(this, ctx, scaleX, scaleY); - node.clear(); - }; - - proto._drawDot = cc.DrawNode.CanvasRenderCmd.prototype._drawDot; - proto._drawSegment = cc.DrawNode.CanvasRenderCmd.prototype._drawSegment; - proto._drawPoly = cc.DrawNode.CanvasRenderCmd.prototype._drawPoly; - -})(); diff --git a/cocos2d/physics/CCPhysicsDebugNodeWebGLRenderCmd.js b/cocos2d/physics/CCPhysicsDebugNodeWebGLRenderCmd.js index 38ddf9f630..e69de29bb2 100644 --- a/cocos2d/physics/CCPhysicsDebugNodeWebGLRenderCmd.js +++ b/cocos2d/physics/CCPhysicsDebugNodeWebGLRenderCmd.js @@ -1,53 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -/** - * cc.PhysicsDebugNode's rendering objects of WebGL - */ -(function(){ - cc.PhysicsDebugNode.WebGLRenderCmd = function (renderableObject) { - cc.Node.WebGLRenderCmd.call(this, renderableObject); - this._needDraw = true; - }; - - cc.PhysicsDebugNode.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype); - cc.PhysicsDebugNode.WebGLRenderCmd.prototype.constructor = cc.PhysicsDebugNode.WebGLRenderCmd; - - cc.PhysicsDebugNode.WebGLRenderCmd.prototype.rendering = function (ctx) { - var node = this._node; - if (!node._space) - return; - - node._space.eachShape(cc.DrawShape.bind(node)); - node._space.eachConstraint(cc.DrawConstraint.bind(node)); - - //cc.DrawNode.prototype.draw.call(node); - cc.glBlendFunc(node._blendFunc.src, node._blendFunc.dst); - this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix); - node._render(); - - node.clear(); - }; -})(); \ No newline at end of file diff --git a/cocos2d/physics/CCPhysicsSprite.js b/cocos2d/physics/CCPhysicsSprite.js index 0bb9db8627..e69de29bb2 100644 --- a/cocos2d/physics/CCPhysicsSprite.js +++ b/cocos2d/physics/CCPhysicsSprite.js @@ -1,447 +0,0 @@ -/** - * Copyright (c) 2012 Scott Lembcke and Howling Moon Software - * Copyright (c) 2008-2010 Ricardo Quesada - * Copyright (c) 2011-2012 cocos2d-x.org - * Copyright (c) 2013-2014 Chukong Technologies Inc. - * - * 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. - */ - -/** A CCSprite subclass that is bound to a physics body. - It works with: - - Chipmunk: Preprocessor macro CC_ENABLE_CHIPMUNK_INTEGRATION should be defined - - Objective-Chipmunk: Preprocessor macro CC_ENABLE_CHIPMUNK_INTEGRATION should be defined - - Box2d: Preprocessor macro CC_ENABLE_BOX2D_INTEGRATION should be defined - - Features and Limitations: - - Scale and Skew properties are ignored. - - Position and rotation are going to updated from the physics body - - If you update the rotation or position manually, the physics body will be updated - - You can't eble both Chipmunk support and Box2d support at the same time. Only one can be enabled at compile time - */ -(function () { - var box2dAPI = { - _ignoreBodyRotation:false, - _body:null, - _PTMRatio:32, - _rotation:1, - /** - * Create a PhysicsSprite with filename and rect - * Constructor of cc.PhysicsSprite for Box2d - * @param {String|cc.Texture2D|cc.SpriteFrame} fileName - * @param {cc.Rect} rect - * @example - * - * 1.Create a sprite with image path and rect - * var physicsSprite1 = new cc.PhysicsSprite("res/HelloHTML5World.png"); - * var physicsSprite2 = new cc.PhysicsSprite("res/HelloHTML5World.png",cc.rect(0,0,480,320)); - * - * 2.Create a sprite with a sprite frame name. Must add "#" before fame name. - * var physicsSprite = new cc.PhysicsSprite('#grossini_dance_01.png'); - * - * 3.Create a sprite with a sprite frame - * var spriteFrame = cc.spriteFrameCache.getSpriteFrame("grossini_dance_01.png"); - * var physicsSprite = new cc.PhysicsSprite(spriteFrame); - * - * 4.Creates a sprite with an existing texture contained in a CCTexture2D object - * After creation, the rect will be the size of the texture, and the offset will be (0,0). - * var texture = cc.textureCache.addImage("HelloHTML5World.png"); - * var physicsSprite1 = new cc.PhysicsSprite(texture); - * var physicsSprite2 = new cc.PhysicsSprite(texture, cc.rect(0,0,480,320)); - * - */ - ctor:function(fileName, rect){ - cc.Sprite.prototype.ctor.call(this); - - if (fileName === undefined) { - cc.PhysicsSprite.prototype.init.call(this); - }else if (cc.isString(fileName)) { - if (fileName[0] === "#") { - //init with a sprite frame name - var frameName = fileName.substr(1, fileName.length - 1); - var spriteFrame = cc.spriteFrameCache.getSpriteFrame(frameName); - this.initWithSpriteFrame(spriteFrame); - } else { - //init with filename and rect - this.init(fileName, rect); - } - }else if (cc.isObject(fileName)) { - if (fileName instanceof cc.Texture2D) { - //init with texture and rect - this.initWithTexture(fileName, rect); - } else if (fileName instanceof cc.SpriteFrame) { - //init with a sprite frame - this.initWithSpriteFrame(fileName); - } - } - //this._transformCmd = new cc.PhysicsSpriteTransformCmdCanvas(this); - //cc.rendererCanvas.pushRenderCommand(this._transformCmd); - }, - - //visit: function(){ - // cc.Sprite.prototype.visit.call(this); - // cc.rendererCanvas.pushRenderCommand(this._transformCmd); - //}, - - /** - * set body - * @param {Box2D.Dynamics.b2Body} body - */ - setBody:function (body) { - this._body = body; - }, - - /** - * get body - * @return {Box2D.Dynamics.b2Body} - */ - getBody:function () { - return this._body; - }, - - /** - * set PTM ratio - * @param {Number} r - */ - setPTMRatio:function (r) { - this._PTMRatio = r; - }, - - /** - * get PTM ration - * @return {Number} - */ - getPTMRatio:function () { - return this._PTMRatio; - }, - - /** - * get position - * @return {cc.Point} - */ - getPosition:function () { - var pos = this._body.GetPosition(); - var locPTMRatio =this._PTMRatio; - return cc.p(pos.x * locPTMRatio, pos.y * locPTMRatio); - }, - - /** - * set position - * @param {cc.Point} p - */ - setPosition:function (p) { - var angle = this._body.GetAngle(); - var locPTMRatio =this._PTMRatio; - this._body.setTransform(Box2D.b2Vec2(p.x / locPTMRatio, p.y / locPTMRatio), angle); - this.setNodeDirty(); - }, - - /** - * get rotation - * @return {Number} - */ - getRotation:function () { - return (this._ignoreBodyRotation ? cc.radiansToDegrees(this._rotationRadians) : cc.radiansToDegrees(this._body.GetAngle())); - }, - - /** - * set rotation - * @param {Number} r - */ - setRotation:function (r) { - if (this._ignoreBodyRotation) { - this._rotation = r; - } else { - var locBody = this._body; - var p = locBody.GetPosition(); - locBody.SetTransform(p, cc.degreesToRadians(r)); - } - this.setNodeDirty(); - }, - _syncPosition:function () { - var pos = this._body.GetPosition(); - this._position.x = pos.x * this._PTMRatio; - this._position.y = pos.y * this._PTMRatio; - this._rotationRadians = this._rotation * (Math.PI / 180); - }, - _syncRotation:function () { - this._rotationRadians = this._body.GetAngle(); - }, - /** - * visit - */ - visit:function () { - if (this._body && this._PTMRatio) { - this._syncPosition(); - if (!this._ignoreBodyRotation) - this._syncRotation(); - } - else { - cc.log("PhysicsSprite body or PTIMRatio was not set"); - } - this._super(); - }, - - /** - * set whether to ingore body's rotation - * @param {Boolean} b - */ - setIgnoreBodyRotation: function(b) { - this._ignoreBodyRotation = b; - } - }; - - var chipmunkAPI = { - _ignoreBodyRotation:false, - _body:null, //physics body - _rotation:1, - - /** - * Create a PhysicsSprite with filename and rect - * Constructor of cc.PhysicsSprite for chipmunk - * @param {String|cc.Texture2D|cc.SpriteFrame} fileName - * @param {cc.Rect} rect - * @example - * - * 1.Create a sprite with image path and rect - * var physicsSprite1 = new cc.PhysicsSprite("res/HelloHTML5World.png"); - * var physicsSprite2 = new cc.PhysicsSprite("res/HelloHTML5World.png",cc.rect(0,0,480,320)); - * - * 2.Create a sprite with a sprite frame name. Must add "#" before frame name. - * var physicsSprite = new cc.PhysicsSprite('#grossini_dance_01.png'); - * - * 3.Create a sprite with a sprite frame - * var spriteFrame = cc.spriteFrameCache.getSpriteFrame("grossini_dance_01.png"); - * var physicsSprite = new cc.PhysicsSprite(spriteFrame); - * - * 4.Creates a sprite with an exsiting texture contained in a CCTexture2D object - * After creation, the rect will be the size of the texture, and the offset will be (0,0). - * var texture = cc.textureCache.addImage("HelloHTML5World.png"); - * var physicsSprite1 = new cc.PhysicsSprite(texture); - * var physicsSprite2 = new cc.PhysicsSprite(texture, cc.rect(0,0,480,320)); - * - */ - ctor:function(fileName, rect){ - cc.Sprite.prototype.ctor.call(this); - - if (fileName === undefined) { - cc.PhysicsSprite.prototype.init.call(this); - }else if (cc.isString(fileName)) { - if (fileName[0] === "#") { - //init with a sprite frame name - var frameName = fileName.substr(1, fileName.length - 1); - var spriteFrame = cc.spriteFrameCache.getSpriteFrame(frameName); - this.initWithSpriteFrame(spriteFrame); - } else { - //init with filename and rect - this.init(fileName, rect); - } - }else if (cc.isObject(fileName)) { - if (fileName instanceof cc.Texture2D) { - //init with texture and rect - this.initWithTexture(fileName, rect); - } else if (fileName instanceof cc.SpriteFrame) { - //init with a sprite frame - this.initWithSpriteFrame(fileName); - } - } - - cc.renderer.pushRenderCommand(this._renderCmd); - }, - - visit: function(){ - cc.renderer.pushRenderCommand(this._renderCmd); - cc.Sprite.prototype.visit.call(this); - }, - - /** - * set body - * @param {cp.Body} body - */ - setBody:function (body) { - this._body = body; - }, - - /** - * get body - * @returns {cp.Body} - */ - getBody:function () { - return this._body; - }, - - /** - * get position - * @return {cc.Point} - */ - getPosition:function () { - var locBody = this._body; - return {x:locBody.p.x, y:locBody.p.y}; - }, - - /** - * get position x - * @return {Number} - */ - getPositionX:function () { - return this._body.p.x; - }, - - /** - * get position y - * @return {Number} - */ - getPositionY:function () { - return this._body.p.y; - }, - - /** - * set position - * @param {cc.Point|Number}newPosOrxValue - * @param {Number}yValue - */ - setPosition:function (newPosOrxValue, yValue) { - if (yValue === undefined) { - this._body.p.x = newPosOrxValue.x; - this._body.p.y = newPosOrxValue.y; - } else { - this._body.p.x = newPosOrxValue; - this._body.p.y = yValue; - } - //this._syncPosition(); - }, - - /** - * set position x - * @param {Number} xValue - */ - setPositionX:function (xValue) { - this._body.p.x = xValue; - //this._syncPosition(); - }, - - /** - * set position y - * @param {Number} yValue - */ - setPositionY:function (yValue) { - this._body.p.y = yValue; - //this._syncPosition(); - }, - - _syncPosition:function () { - var locPosition = this._position, locBody = this._body; - if (locPosition.x !== locBody.p.x || locPosition.y !== locBody.p.y) { - cc.Sprite.prototype.setPosition.call(this, locBody.p.x, locBody.p.y); - } - }, - - /** - * get rotation - * @return {Number} - */ - getRotation:function () { - return this._ignoreBodyRotation ? this._rotationX : -cc.radiansToDegrees(this._body.a); - }, - - /** - * set rotation - * @param {Number} r - */ - setRotation:function (r) { - if (this._ignoreBodyRotation) { - cc.Sprite.prototype.setRotation.call(this, r); - } else { - this._body.a = -cc.degreesToRadians(r); - //this._syncRotation(); - } - }, - _syncRotation:function () { - if (this._rotationX !== -cc.radiansToDegrees(this._body.a)) { - cc.Sprite.prototype.setRotation.call(this, -cc.radiansToDegrees(this._body.a)); - } - }, - - /** - * get the affine transform matrix of node to parent coordinate frame - * @return {cc.AffineTransform} - */ - getNodeToParentTransform:function () { - return this._renderCmd.getNodeToParentTransform(); - }, - - /** - * whether dirty - * @return {Boolean} - */ - isDirty:function(){ - return !this._body.isSleeping(); - }, - setDirty: function(){ }, - - /** - * set whether to ignore rotation of body - * @param {Boolean} b - */ - setIgnoreBodyRotation: function(b) { - this._ignoreBodyRotation = b; - }, - - _createRenderCmd: function(){ - if(cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new cc.PhysicsSprite.CanvasRenderCmd(this); - else - return new cc.PhysicsSprite.WebGLRenderCmd(this); - } - }; - cc.PhysicsSprite = cc.Sprite.extend(chipmunkAPI); - cc.PhysicsSprite._className = "PhysicsSprite"; - var _p = cc.PhysicsSprite.prototype; - // Extended properties - /** @expose */ - _p.body; - cc.defineGetterSetter(_p, "body", _p.getBody, _p.setBody); - /** @expose */ - _p.dirty; - cc.defineGetterSetter(_p, "dirty", _p.isDirty, _p.setDirty); - - - /** - * Create a PhysicsSprite with filename and rect - * @deprecated since v3.0, please use new cc.PhysicsSprite(fileName, rect) instead - * @param {String|cc.Texture2D|cc.SpriteFrame} fileName - * @param {cc.Rect} rect - * @return {cc.PhysicsSprite} - */ - cc.PhysicsSprite.create = function (fileName, rect) { - return new cc.PhysicsSprite(fileName, rect); - }; - - /** - * @deprecated since v3.0, please use new cc.PhysicsSprite(spriteFrameName) instead - * @type {Function} - */ - cc.PhysicsSprite.createWithSpriteFrameName = cc.PhysicsSprite.create; - - /** - * @deprecated since v3.0, please use new cc.PhysicsSprite(spriteFrame) instead - * @type {Function} - */ - cc.PhysicsSprite.createWithSpriteFrame = cc.PhysicsSprite.create; -})(); diff --git a/cocos2d/physics/CCPhysicsSpriteCanvasRenderCmd.js b/cocos2d/physics/CCPhysicsSpriteCanvasRenderCmd.js index ae95d94df9..e69de29bb2 100644 --- a/cocos2d/physics/CCPhysicsSpriteCanvasRenderCmd.js +++ b/cocos2d/physics/CCPhysicsSpriteCanvasRenderCmd.js @@ -1,93 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -/** - * cc.PhysicsSprite's rendering objects of Canvas - */ -(function(){ - cc.PhysicsSprite.CanvasRenderCmd = function(renderableObject){ - cc.Sprite.CanvasRenderCmd.call(this, renderableObject); - this._needDraw = true; - }; - - var proto = cc.PhysicsSprite.CanvasRenderCmd.prototype = Object.create(cc.Sprite.CanvasRenderCmd.prototype); - proto.constructor = cc.PhysicsSprite.CanvasRenderCmd; - - proto.rendering = function(ctx, scaleX, scaleY){ - // This is a special class - // Sprite can not obtain sign - // So here must to calculate of each frame - var node = this._node; - node._syncPosition(); - if(!node._ignoreBodyRotation) - node._syncRotation(); - this.transform(this.getParentRenderCmd()); - - cc.Sprite.CanvasRenderCmd.prototype.rendering.call(this, ctx, scaleX, scaleY); - }; - - proto.getNodeToParentTransform = function(){ - var node = this._node; - - var t = this._transform;// quick reference - // base position - var locBody = node._body, locScaleX = node._scaleX, locScaleY = node._scaleY, locAnchorPIP = this._anchorPointInPoints; - t.tx = locBody.p.x; - t.ty = locBody.p.y; - - // rotation Cos and Sin - var radians = -locBody.a; - var Cos = 1, Sin = 0; - if (radians && !node._ignoreBodyRotation) { - Cos = Math.cos(radians); - Sin = Math.sin(radians); - } - - // base abcd - t.a = t.d = Cos; - t.b = -Sin; - t.c = Sin; - - // scale - if (locScaleX !== 1 || locScaleY !== 1) { - t.a *= locScaleX; - t.c *= locScaleX; - t.b *= locScaleY; - t.d *= locScaleY; - } - - // adjust anchorPoint - t.tx += Cos * -locAnchorPIP.x * locScaleX + -Sin * locAnchorPIP.y * locScaleY; - t.ty -= Sin * -locAnchorPIP.x * locScaleX + Cos * locAnchorPIP.y * locScaleY; - - // if ignore anchorPoint - if (this._ignoreAnchorPointForPosition) { - t.tx += locAnchorPIP.x; - t.ty += locAnchorPIP.y; - } - - return this._transform; - }; - -})(); \ No newline at end of file diff --git a/cocos2d/physics/CCPhysicsSpriteWebGLRenderCmd.js b/cocos2d/physics/CCPhysicsSpriteWebGLRenderCmd.js index 339610ed36..e69de29bb2 100644 --- a/cocos2d/physics/CCPhysicsSpriteWebGLRenderCmd.js +++ b/cocos2d/physics/CCPhysicsSpriteWebGLRenderCmd.js @@ -1,92 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -/** - * cc.PhysicsSprite's rendering objects of WebGL - */ -(function(){ - cc.PhysicsSprite.WebGLRenderCmd = function(renderableObject){ - cc.Sprite.WebGLRenderCmd.call(this, renderableObject); - this._needDraw = true; - }; - - var proto = cc.PhysicsSprite.WebGLRenderCmd.prototype = Object.create(cc.Sprite.WebGLRenderCmd.prototype); - proto.constructor = cc.PhysicsSprite.WebGLRenderCmd; - - proto.rendering = function(ctx){ - // This is a special class - // Sprite can not obtain sign - // So here must to calculate of each frame - var node = this._node; - node._syncPosition(); - if(!node._ignoreBodyRotation) - node._syncRotation(); - this.transform(this.getParentRenderCmd(), true); - - cc.Sprite.WebGLRenderCmd.prototype.rendering.call(this, ctx); - }; - - proto.getNodeToParentTransform = function(){ - var node = this._node; - var locBody = node._body, locAnchorPIP = this._anchorPointInPoints, locScaleX = node._scaleX, locScaleY = node._scaleY; - var x = locBody.p.x; - var y = locBody.p.y; - - if (this._ignoreAnchorPointForPosition) { - x += locAnchorPIP.x; - y += locAnchorPIP.y; - } - - // Make matrix - var radians = locBody.a, c = 1, s=0; - if (radians && !node._ignoreBodyRotation) { - c = Math.cos(radians); - s = Math.sin(radians); - } - - // Although scale is not used by physics engines, it is calculated just in case - // the sprite is animated (scaled up/down) using actions. - // For more info see: http://www.cocos2d-iphone.org/forum/topic/68990 - if (!cc._rectEqualToZero(locAnchorPIP)) { - x += c * -locAnchorPIP.x * locScaleX + -s * -locAnchorPIP.y * locScaleY; - y += s * -locAnchorPIP.x * locScaleX + c * -locAnchorPIP.y * locScaleY; - } - - // Rot, Translate Matrix - this._transform = cc.affineTransformMake(c * locScaleX, s * locScaleX, - -s * locScaleY, c * locScaleY, x, y); - - return this._transform; - }; - - proto.updateTransform = function(){ - var node = this._node; - var dirty = node.isDirty(); - if(dirty){ - var cmd = node._renderCmd; - cmd && cmd.setDirtyRecursively(true); - } - cc.Sprite.WebGLRenderCmd.prototype.updateTransform.call(this); - }; -})(); \ No newline at end of file diff --git a/cocos2d/progress-timer/CCProgressTimer.js b/cocos2d/progress-timer/CCProgressTimer.js index 8b7443db23..65cad9542c 100644 --- a/cocos2d/progress-timer/CCProgressTimer.js +++ b/cocos2d/progress-timer/CCProgressTimer.js @@ -278,9 +278,6 @@ cc.ProgressTimer = cc.Node.extend(/** @lends cc.ProgressTimer# */{ }, _createRenderCmd: function(){ - if(cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new cc.ProgressTimer.CanvasRenderCmd(this); - else return new cc.ProgressTimer.WebGLRenderCmd(this); } }); diff --git a/cocos2d/progress-timer/CCProgressTimerCanvasRenderCmd.js b/cocos2d/progress-timer/CCProgressTimerCanvasRenderCmd.js index 715fd6c50f..e69de29bb2 100644 --- a/cocos2d/progress-timer/CCProgressTimerCanvasRenderCmd.js +++ b/cocos2d/progress-timer/CCProgressTimerCanvasRenderCmd.js @@ -1,274 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -/** - * cc.ProgressTimer's rendering objects of Canvas - */ -(function(){ - cc.ProgressTimer.CanvasRenderCmd = function(renderableObject){ - cc.Node.CanvasRenderCmd.call(this, renderableObject); - this._needDraw = true; - - this._PI180 = Math.PI / 180; - this._barRect = cc.rect(0, 0, 0, 0); - this._origin = cc.p(0, 0); - this._radius = 0; - this._startAngle = 270; - this._endAngle = 270; - this._counterClockWise = false; - }; - - var proto = cc.ProgressTimer.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype); - proto.constructor = cc.ProgressTimer.CanvasRenderCmd; - - proto.rendering = function (ctx, scaleX, scaleY) { - var wrapper = ctx || cc._renderContext,context = wrapper.getContext(), node = this._node, locSprite = node._sprite; - var locTextureCoord = locSprite._renderCmd._textureCoord, alpha = locSprite._renderCmd._displayedOpacity / 255; - - if (locTextureCoord.width === 0 || locTextureCoord.height === 0) - return; - if (!locSprite._texture || !locTextureCoord.validRect || alpha === 0) - return; - - wrapper.setTransform(this._worldTransform, scaleX, scaleY); - wrapper.setCompositeOperation(locSprite._blendFuncStr); - wrapper.setGlobalAlpha(alpha); - - var locRect = locSprite._rect, locOffsetPosition = locSprite._offsetPosition; - var locX = locOffsetPosition.x, - locY = -locOffsetPosition.y - locRect.height, - locWidth = locRect.width, - locHeight = locRect.height; - - wrapper.save(); - if (locSprite._flippedX) { - locX = -locX - locWidth; - context.scale(-1, 1); - } - if (locSprite._flippedY) { - locY = locOffsetPosition.y; - context.scale(1, -1); - } - - //clip - if (node._type === cc.ProgressTimer.TYPE_BAR) { - var locBarRect = this._barRect; - context.beginPath(); - context.rect(locBarRect.x * scaleX, locBarRect.y * scaleY, locBarRect.width * scaleX, locBarRect.height * scaleY); - context.clip(); - context.closePath(); - } else if (node._type === cc.ProgressTimer.TYPE_RADIAL) { - var locOriginX = this._origin.x * scaleX; - var locOriginY = this._origin.y * scaleY; - context.beginPath(); - context.arc(locOriginX, locOriginY, this._radius * scaleY, this._PI180 * this._startAngle, this._PI180 * this._endAngle, this._counterClockWise); - context.lineTo(locOriginX, locOriginY); - context.clip(); - context.closePath(); - } - - //draw sprite - var image = locSprite._texture.getHtmlElementObj(); - if (locSprite._renderCmd._colorized) { - context.drawImage(image, - 0, 0, locTextureCoord.width, locTextureCoord.height, - locX * scaleX, locY * scaleY, locWidth * scaleX, locHeight * scaleY); - } else { - context.drawImage(image, - locTextureCoord.renderX, locTextureCoord.renderY, locTextureCoord.width, locTextureCoord.height, - locX * scaleX, locY * scaleY, locWidth * scaleX, locHeight * scaleY); - } - wrapper.restore(); - cc.g_NumberOfDraws++; - }; - - proto.releaseData = function(){}; - - proto.initCmd = function(){}; - - proto._updateProgress = function(){ - var node = this._node; - var locSprite = node._sprite; - var sw = locSprite.width, sh = locSprite.height; - var locMidPoint = node._midPoint; - - if (node._type === cc.ProgressTimer.TYPE_RADIAL) { - this._radius = Math.round(Math.sqrt(sw * sw + sh * sh)); - var locStartAngle, locEndAngle, locCounterClockWise = false, locOrigin = this._origin; - locOrigin.x = sw * locMidPoint.x; - locOrigin.y = -sh * locMidPoint.y; - - if (node._reverseDirection) { - locEndAngle = 270; - locStartAngle = 270 - 3.6 * node._percentage; - } else { - locStartAngle = -90; - locEndAngle = -90 + 3.6 * node._percentage; - } - - if (locSprite._flippedX) { - locOrigin.x -= sw * (node._midPoint.x * 2); - locStartAngle = -locStartAngle; - locEndAngle = -locEndAngle; - locStartAngle -= 180; - locEndAngle -= 180; - locCounterClockWise = !locCounterClockWise; - } - if (locSprite._flippedY) { - locOrigin.y += sh * (node._midPoint.y * 2); - locCounterClockWise = !locCounterClockWise; - locStartAngle = -locStartAngle; - locEndAngle = -locEndAngle; - } - - this._startAngle = locStartAngle; - this._endAngle = locEndAngle; - this._counterClockWise = locCounterClockWise; - } else { - var locBarChangeRate = node._barChangeRate; - var percentageF = node._percentage / 100; - var locBarRect = this._barRect; - - var drewSize = cc.size((sw * (1 - locBarChangeRate.x)), (sh * (1 - locBarChangeRate.y))); - var drawingSize = cc.size((sw - drewSize.width) * percentageF, (sh - drewSize.height) * percentageF); - var currentDrawSize = cc.size(drewSize.width + drawingSize.width, drewSize.height + drawingSize.height); - - var startPoint = cc.p(sw * locMidPoint.x, sh * locMidPoint.y); - - var needToLeft = startPoint.x - currentDrawSize.width / 2; - if ((locMidPoint.x > 0.5) && (currentDrawSize.width / 2 >= sw - startPoint.x)) - needToLeft = sw - currentDrawSize.width; - - var needToTop = startPoint.y - currentDrawSize.height / 2; - if ((locMidPoint.y > 0.5) && (currentDrawSize.height / 2 >= sh - startPoint.y)) - needToTop = sh - currentDrawSize.height; - - //left pos - locBarRect.x = 0; - var flipXNeed = 1; - if (locSprite._flippedX) { - locBarRect.x -= currentDrawSize.width; - flipXNeed = -1; - } - - if (needToLeft > 0) - locBarRect.x += needToLeft * flipXNeed; - - //right pos - locBarRect.y = 0; - var flipYNeed = 1; - if (locSprite._flippedY) { - locBarRect.y += currentDrawSize.height; - flipYNeed = -1; - } - - if (needToTop > 0) - locBarRect.y -= needToTop * flipYNeed; - - //clip width and clip height - locBarRect.width = currentDrawSize.width; - locBarRect.height = -currentDrawSize.height; - } - }; - - proto._updateColor = function(){}; - - proto._syncStatus = function (parentCmd) { - var node = this._node; - if(!node._sprite) - return; - var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag; - var parentNode = parentCmd ? parentCmd._node : null; - - if(parentNode && parentNode._cascadeColorEnabled && (parentCmd._dirtyFlag & flags.colorDirty)) - locFlag |= flags.colorDirty; - - if(parentNode && parentNode._cascadeOpacityEnabled && (parentCmd._dirtyFlag & flags.opacityDirty)) - locFlag |= flags.opacityDirty; - - if(parentCmd && (parentCmd._dirtyFlag & flags.transformDirty)) - locFlag |= flags.transformDirty; - - this._dirtyFlag = locFlag; - - var spriteCmd = node._sprite._renderCmd; - var spriteFlag = spriteCmd._dirtyFlag; - - var colorDirty = spriteFlag & flags.colorDirty, - opacityDirty = spriteFlag & flags.opacityDirty; - - if (colorDirty){ - spriteCmd._syncDisplayColor(); - } - - if (opacityDirty){ - spriteCmd._syncDisplayOpacity(); - } - - if(colorDirty || opacityDirty){ - spriteCmd._updateColor(); - //this._updateColor(); - } - - if (locFlag & flags.transformDirty) { - //update the transform - this.transform(parentCmd); - } - - if (locFlag & flags.orderDirty) { - this._dirtyFlag = this._dirtyFlag & flags.orderDirty ^ this._dirtyFlag; - } - }; - - proto.updateStatus = function () { - var node = this._node; - if(!node._sprite) - return; - var flags = cc.Node._dirtyFlags, locFlag = this._dirtyFlag; - var spriteCmd = node._sprite._renderCmd; - var spriteFlag = spriteCmd._dirtyFlag; - - var colorDirty = spriteFlag & flags.colorDirty, - opacityDirty = spriteFlag & flags.opacityDirty; - - if(colorDirty){ - spriteCmd._updateDisplayColor(); - } - - if(opacityDirty){ - spriteCmd._updateDisplayOpacity(); - } - - if(colorDirty || opacityDirty){ - spriteCmd._updateColor(); - //this._updateColor(); - } - - if(locFlag & flags.transformDirty){ - //update the transform - this.transform(this.getParentRenderCmd(), true); - } - this._dirtyFlag = 0; - }; -})(); \ No newline at end of file diff --git a/cocos2d/render-texture/CCRenderTexture.js b/cocos2d/render-texture/CCRenderTexture.js index 5ce1a44e3a..c689c9ead0 100644 --- a/cocos2d/render-texture/CCRenderTexture.js +++ b/cocos2d/render-texture/CCRenderTexture.js @@ -126,9 +126,6 @@ cc.RenderTexture = cc.Node.extend(/** @lends cc.RenderTexture# */{ }, _createRenderCmd: function(){ - if(cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new cc.RenderTexture.CanvasRenderCmd(this); - else return new cc.RenderTexture.WebGLRenderCmd(this); }, diff --git a/cocos2d/render-texture/CCRenderTextureCanvasRenderCmd.js b/cocos2d/render-texture/CCRenderTextureCanvasRenderCmd.js index 854ebba1cc..e69de29bb2 100644 --- a/cocos2d/render-texture/CCRenderTextureCanvasRenderCmd.js +++ b/cocos2d/render-texture/CCRenderTextureCanvasRenderCmd.js @@ -1,107 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -(function(){ - cc.RenderTexture.CanvasRenderCmd = function(renderableObject){ - cc.Node.CanvasRenderCmd.call(this, renderableObject); - this._needDraw = true; - this._clearColorStr = "rgba(255,255,255,1)"; - - this._cacheCanvas = document.createElement('canvas'); - this._cacheContext = new cc.CanvasContextWrapper(this._cacheCanvas.getContext('2d')); - }; - - var proto = cc.RenderTexture.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype); - proto.constructor = cc.RenderTexture.CanvasRenderCmd; - - proto.cleanup = function(){ - this._cacheContext = null; - this._cacheCanvas = null; - }; - - proto.clearStencil = function (stencilValue) { }; - - proto.setVirtualViewport = function(rtBegin, fullRect, fullViewport) {}; - - proto.updateClearColor = function(clearColor){ - this._clearColorStr = "rgba(" + (0 | clearColor.r) + "," + (0 | clearColor.g) + "," + (0 | clearColor.b) + "," + clearColor.a / 255 + ")"; - }; - - proto.initWithWidthAndHeight = function(width, height, format, depthStencilFormat){ - var node = this._node; - var locCacheCanvas = this._cacheCanvas, locScaleFactor = cc.contentScaleFactor(); - locCacheCanvas.width = 0 | (width * locScaleFactor); - locCacheCanvas.height = 0 | (height * locScaleFactor); - - var texture = new cc.Texture2D(); - texture.initWithElement(locCacheCanvas); - texture.handleLoadedTexture(); - - var locSprite = node.sprite = new cc.Sprite(texture); - locSprite.setBlendFunc(cc.ONE, cc.ONE_MINUS_SRC_ALPHA); - // Disabled by default. - node.autoDraw = false; - // add sprite for backward compatibility - node.addChild(locSprite); - return true; - }; - - proto.begin = function(){}; - - proto._beginWithClear = function(r, g, b, a, depthValue, stencilValue, flags){ - r = r || 0; - g = g || 0; - b = b || 0; - a = isNaN(a) ? 255 : a; - - var context = this._cacheContext.getContext(); - var locCanvas = this._cacheCanvas; - context.setTransform(1,0,0,1,0,0); - this._cacheContext.setFillStyle("rgba(" + (0 | r) + "," + (0 | g) + "," + (0 | b) + "," + a / 255 + ")"); - context.clearRect(0, 0, locCanvas.width, locCanvas.height); - context.fillRect(0, 0, locCanvas.width, locCanvas.height); - }; - - proto.end = function(){ - var node = this._node; - - var scale = cc.contentScaleFactor(); - cc.renderer._renderingToCacheCanvas(this._cacheContext, node.__instanceId, scale, scale); - }; - - proto.clearRect = function(x, y, width, height){ - this._cacheContext.clearRect(x, y, width, -height); - }; - - proto.clearDepth = function(depthValue){ - cc.log("clearDepth isn't supported on Cocos2d-Html5"); - }; - - proto.visit = function(parentCmd){ - var node = this._node; - this._syncStatus(parentCmd); - node.sprite.visit(this); - this._dirtyFlag = 0; - }; -})(); \ No newline at end of file diff --git a/cocos2d/shaders/CCGLProgram.js b/cocos2d/shaders/CCGLProgram.js index 1f55478576..6219aced79 100644 --- a/cocos2d/shaders/CCGLProgram.js +++ b/cocos2d/shaders/CCGLProgram.js @@ -630,6 +630,9 @@ cc.GLProgram = cc.Class.extend(/** @lends cc.GLProgram# */{ this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_PMATRIX], false, cc.projection_matrix_stack.top.mat); }, + _updateProjectionUniform: function(){ + this._glContext.uniformMatrix4fv(this._uniforms[cc.UNIFORM_PMATRIX], false, cc.projection_matrix_stack.top.mat); + }, /** * returns the vertexShader error log * @return {String} diff --git a/cocos2d/shaders/CCShaderCache.js b/cocos2d/shaders/CCShaderCache.js index f78780ddb6..fc854ee5ec 100644 --- a/cocos2d/shaders/CCShaderCache.js +++ b/cocos2d/shaders/CCShaderCache.js @@ -36,7 +36,9 @@ cc.shaderCache = /** @lends cc.shaderCache# */{ * @constant * @type {Number} */ - TYPE_POSITION_TEXTURECOLOR: 0, + TYPE_POSITION_TEXTURECOLOR: 0, + + /** * @public * @constant @@ -79,12 +81,21 @@ cc.shaderCache = /** @lends cc.shaderCache# */{ * @type {Number} */ TYPE_POSITION_LENGTH_TEXTURECOLOR: 7, + + /** + * PITFOREST + * @public + * @constant + * @type {Number} + */ + TYPE_POSITION_TEXTURECOLOR_ALPHATEST_BATCHED: 8, + /** * @public * @constant * @type {Number} */ - TYPE_MAX: 8, + TYPE_MAX: 9, _programs: {}, @@ -95,6 +106,13 @@ cc.shaderCache = /** @lends cc.shaderCache# */{ _loadDefaultShader: function (program, type) { switch (type) { + case this.TYPE_POSITION_TEXTURECOLOR_ALPHATEST_BATCHED: + program.initWithVertexShaderByteArray(cc.SHADER_POSITION_TEXTURE_COLOR_VERT_BATCHED, cc.SHADER_POSITION_TEXTURE_COLOR_ALPHATEST_FRAG); + + program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION); + program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR); + program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS); + break; case this.TYPE_POSITION_TEXTURECOLOR: program.initWithVertexShaderByteArray(cc.SHADER_POSITION_TEXTURE_COLOR_VERT, cc.SHADER_POSITION_TEXTURE_COLOR_FRAG); @@ -166,6 +184,12 @@ cc.shaderCache = /** @lends cc.shaderCache# */{ this._programs[cc.SHADER_POSITION_TEXTURECOLOR] = program; this._programs["ShaderPositionTextureColor"] = program; + // Position Texture Color alpha test + program = new cc.GLProgram(); + this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURECOLOR_ALPHATEST_BATCHED); + this._programs[cc.SHADER_POSITION_TEXTURECOLORALPHATEST_BATCHED] = program; + this._programs["ShaderPositionTextureColorAlphaTestBatched"] = program; + // Position Texture Color alpha test program = new cc.GLProgram(); this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURECOLOR_ALPHATEST); diff --git a/cocos2d/shaders/CCShaders.js b/cocos2d/shaders/CCShaders.js index 437ce589aa..6c799d73c2 100644 --- a/cocos2d/shaders/CCShaders.js +++ b/cocos2d/shaders/CCShaders.js @@ -222,6 +222,23 @@ cc.SHADER_POSITION_TEXTURE_COLOR_FRAG = + " gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord); \n" + "}"; +/* PITFOREST +*/ +cc.SHADER_POSITION_TEXTURE_COLOR_VERT_BATCHED = + "attribute vec4 a_position; \n" + + "attribute vec2 a_texCoord; \n" + + "attribute vec4 a_color; \n" + + "attribute mat4 a_mvMatrix;" + + "varying lowp vec4 v_fragmentColor; \n" + + "varying mediump vec2 v_texCoord; \n" + + "void main() \n" + + "{ \n" + //+ " gl_Position = CC_MVPMatrix * a_position; \n" + + " gl_Position = (CC_PMatrix * a_mvMatrix) * a_position; \n" + + " v_fragmentColor = a_color; \n" + + " v_texCoord = a_texCoord; \n" + + "}"; + /** * @constant * @type {String} diff --git a/cocos2d/shape-nodes/CCDrawNode.js b/cocos2d/shape-nodes/CCDrawNode.js index b534b3cf39..8424d460c9 100644 --- a/cocos2d/shape-nodes/CCDrawNode.js +++ b/cocos2d/shape-nodes/CCDrawNode.js @@ -170,349 +170,7 @@ cc.DrawNode.TYPE_SEGMENT = 1; cc.DrawNode.TYPE_POLY = 2; cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { - if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) { - - cc._DrawNodeElement = function (type, verts, fillColor, lineWidth, lineColor, lineCap, isClosePolygon, isFill, isStroke) { - var _t = this; - _t.type = type; - _t.verts = verts || null; - _t.fillColor = fillColor || null; - _t.lineWidth = lineWidth || 0; - _t.lineColor = lineColor || null; - _t.lineCap = lineCap || "butt"; - _t.isClosePolygon = isClosePolygon || false; - _t.isFill = isFill || false; - _t.isStroke = isStroke || false; - }; - - cc.extend(cc.DrawNode.prototype, /** @lends cc.DrawNode# */{ - _className:"DrawNodeCanvas", - - /** - *

The cc.DrawNodeCanvas's constructor.
- * This function will automatically be invoked when you create a node using new construction: "var node = new cc.DrawNodeCanvas()".
- * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.

- */ - ctor: function () { - cc.Node.prototype.ctor.call(this); - var locCmd = this._renderCmd; - locCmd._buffer = this._buffer = []; - locCmd._drawColor = this._drawColor = cc.color(255, 255, 255, 255); - locCmd._blendFunc = this._blendFunc = new cc.BlendFunc(cc.SRC_ALPHA, cc.ONE_MINUS_SRC_ALPHA); - - this.init(); - }, - - /** - * draws a rectangle given the origin and destination point measured in points. - * @param {cc.Point} origin - * @param {cc.Point} destination - * @param {cc.Color} fillColor - * @param {Number} lineWidth - * @param {cc.Color} lineColor - */ - drawRect: function (origin, destination, fillColor, lineWidth, lineColor) { - lineWidth = (lineWidth == null) ? this._lineWidth : lineWidth; - lineColor = lineColor || this.getDrawColor(); - if(lineColor.a == null) - lineColor.a = 255; - - var vertices = [ - origin, - cc.p(destination.x, origin.y), - destination, - cc.p(origin.x, destination.y) - ]; - var element = new cc._DrawNodeElement(cc.DrawNode.TYPE_POLY); - element.verts = vertices; - element.lineWidth = lineWidth; - element.lineColor = lineColor; - element.isClosePolygon = true; - element.isStroke = true; - element.lineCap = "butt"; - element.fillColor = fillColor; - if (fillColor) { - if(fillColor.a == null) - fillColor.a = 255; - element.isFill = true; - } - this._buffer.push(element); - }, - - /** - * draws a circle given the center, radius and number of segments. - * @override - * @param {cc.Point} center center of circle - * @param {Number} radius - * @param {Number} angle angle in radians - * @param {Number} segments - * @param {Boolean} drawLineToCenter - * @param {Number} lineWidth - * @param {cc.Color} color - */ - drawCircle: function (center, radius, angle, segments, drawLineToCenter, lineWidth, color) { - lineWidth = lineWidth || this._lineWidth; - color = color || this.getDrawColor(); - if (color.a == null) - color.a = 255; - - var coef = 2.0 * Math.PI / segments; - var vertices = []; - for (var i = 0; i <= segments; i++) { - var rads = i * coef; - var j = radius * Math.cos(rads + angle) + center.x; - var k = radius * Math.sin(rads + angle) + center.y; - vertices.push(cc.p(j, k)); - } - if (drawLineToCenter) { - vertices.push(cc.p(center.x, center.y)); - } - - var element = new cc._DrawNodeElement(cc.DrawNode.TYPE_POLY); - element.verts = vertices; - element.lineWidth = lineWidth; - element.lineColor = color; - element.isClosePolygon = true; - element.isStroke = true; - this._buffer.push(element); - }, - - /** - * draws a quad bezier path - * @override - * @param {cc.Point} origin - * @param {cc.Point} control - * @param {cc.Point} destination - * @param {Number} segments - * @param {Number} lineWidth - * @param {cc.Color} color - */ - drawQuadBezier: function (origin, control, destination, segments, lineWidth, color) { - lineWidth = lineWidth || this._lineWidth; - color = color || this.getDrawColor(); - if (color.a == null) - color.a = 255; - - var vertices = [], t = 0.0; - for (var i = 0; i < segments; i++) { - var x = Math.pow(1 - t, 2) * origin.x + 2.0 * (1 - t) * t * control.x + t * t * destination.x; - var y = Math.pow(1 - t, 2) * origin.y + 2.0 * (1 - t) * t * control.y + t * t * destination.y; - vertices.push(cc.p(x, y)); - t += 1.0 / segments; - } - vertices.push(cc.p(destination.x, destination.y)); - - var element = new cc._DrawNodeElement(cc.DrawNode.TYPE_POLY); - element.verts = vertices; - element.lineWidth = lineWidth; - element.lineColor = color; - element.isStroke = true; - element.lineCap = "round"; - this._buffer.push(element); - }, - - /** - * draws a cubic bezier path - * @override - * @param {cc.Point} origin - * @param {cc.Point} control1 - * @param {cc.Point} control2 - * @param {cc.Point} destination - * @param {Number} segments - * @param {Number} lineWidth - * @param {cc.Color} color - */ - drawCubicBezier: function (origin, control1, control2, destination, segments, lineWidth, color) { - lineWidth = lineWidth || this._lineWidth; - color = color || this.getDrawColor(); - if (color.a == null) - color.a = 255; - - var vertices = [], t = 0; - for (var i = 0; i < segments; i++) { - var x = Math.pow(1 - t, 3) * origin.x + 3.0 * Math.pow(1 - t, 2) * t * control1.x + 3.0 * (1 - t) * t * t * control2.x + t * t * t * destination.x; - var y = Math.pow(1 - t, 3) * origin.y + 3.0 * Math.pow(1 - t, 2) * t * control1.y + 3.0 * (1 - t) * t * t * control2.y + t * t * t * destination.y; - vertices.push(cc.p(x, y)); - t += 1.0 / segments; - } - vertices.push(cc.p(destination.x, destination.y)); - - var element = new cc._DrawNodeElement(cc.DrawNode.TYPE_POLY); - element.verts = vertices; - element.lineWidth = lineWidth; - element.lineColor = color; - element.isStroke = true; - element.lineCap = "round"; - this._buffer.push(element); - }, - - /** - * draw a CatmullRom curve - * @override - * @param {Array} points - * @param {Number} segments - * @param {Number} lineWidth - * @param {cc.Color} color - */ - drawCatmullRom: function (points, segments, lineWidth, color) { - this.drawCardinalSpline(points, 0.5, segments, lineWidth, color); - }, - - /** - * draw a cardinal spline path - * @override - * @param {Array} config - * @param {Number} tension - * @param {Number} segments - * @param {Number} lineWidth - * @param {cc.Color} color - */ - drawCardinalSpline: function (config, tension, segments, lineWidth, color) { - lineWidth = lineWidth || this._lineWidth; - color = color || this.getDrawColor(); - if(color.a == null) - color.a = 255; - - var vertices = [], p, lt, deltaT = 1.0 / config.length; - for (var i = 0; i < segments + 1; i++) { - var dt = i / segments; - // border - if (dt === 1) { - p = config.length - 1; - lt = 1; - } else { - p = 0 | (dt / deltaT); - lt = (dt - deltaT * p) / deltaT; - } - - // Interpolate - var newPos = cc.cardinalSplineAt( - cc.getControlPointAt(config, p - 1), - cc.getControlPointAt(config, p - 0), - cc.getControlPointAt(config, p + 1), - cc.getControlPointAt(config, p + 2), - tension, lt); - vertices.push(newPos); - } - - var element = new cc._DrawNodeElement(cc.DrawNode.TYPE_POLY); - element.verts = vertices; - element.lineWidth = lineWidth; - element.lineColor = color; - element.isStroke = true; - element.lineCap = "round"; - this._buffer.push(element); - }, - - /** - * draw a dot at a position, with a given radius and color - * @param {cc.Point} pos - * @param {Number} radius - * @param {cc.Color} color - */ - drawDot: function (pos, radius, color) { - color = color || this.getDrawColor(); - if (color.a == null) - color.a = 255; - var element = new cc._DrawNodeElement(cc.DrawNode.TYPE_DOT); - element.verts = [pos]; - element.lineWidth = radius; - element.fillColor = color; - this._buffer.push(element); - }, - - /** - * draws an array of points. - * @override - * @param {Array} points point of array - * @param {Number} radius - * @param {cc.Color} color - */ - drawDots: function(points, radius, color){ - if(!points || points.length == 0) - return; - color = color || this.getDrawColor(); - if (color.a == null) - color.a = 255; - for(var i = 0, len = points.length; i < len; i++) - this.drawDot(points[i], radius, color); - }, - - /** - * draw a segment with a radius and color - * @param {cc.Point} from - * @param {cc.Point} to - * @param {Number} lineWidth - * @param {cc.Color} color - */ - drawSegment: function (from, to, lineWidth, color) { - lineWidth = lineWidth || this._lineWidth; - color = color || this.getDrawColor(); - if (color.a == null) - color.a = 255; - var element = new cc._DrawNodeElement(cc.DrawNode.TYPE_POLY); - element.verts = [from, to]; - element.lineWidth = lineWidth * 2; - element.lineColor = color; - element.isStroke = true; - element.lineCap = "round"; - this._buffer.push(element); - }, - - /** - * draw a polygon with a fill color and line color without copying the vertex list - * @param {Array} verts - * @param {cc.Color} fillColor - * @param {Number} lineWidth - * @param {cc.Color} color - */ - drawPoly_: function (verts, fillColor, lineWidth, color) { - lineWidth = (lineWidth == null ) ? this._lineWidth : lineWidth; - color = color || this.getDrawColor(); - if (color.a == null) - color.a = 255; - var element = new cc._DrawNodeElement(cc.DrawNode.TYPE_POLY); - - element.verts = verts; - element.fillColor = fillColor; - element.lineWidth = lineWidth; - element.lineColor = color; - element.isClosePolygon = true; - element.isStroke = true; - element.lineCap = "round"; - if (fillColor) - element.isFill = true; - this._buffer.push(element); - }, - - /** - * draw a polygon with a fill color and line color, copying the vertex list - * @param {Array} verts - * @param {cc.Color} fillColor - * @param {Number} lineWidth - * @param {cc.Color} color - */ - drawPoly: function (verts, fillColor, lineWidth, color) { - var vertsCopy = []; - for (var i=0; i < verts.length; i++) { - vertsCopy.push(cc.p(verts[i].x, verts[i].y)); - } - return this.drawPoly_(vertsCopy, fillColor, lineWidth, color); - }, - - /** - * Clear the geometry in the node's buffer. - */ - clear: function () { - this._buffer.length = 0; - }, - - _createRenderCmd: function(){ - return new cc.DrawNode.CanvasRenderCmd(this); - } - }); - } - else if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) { + if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) { cc.extend(cc.DrawNode.prototype, { _bufferCapacity:0, diff --git a/cocos2d/shape-nodes/CCDrawNodeCanvasRenderCmd.js b/cocos2d/shape-nodes/CCDrawNodeCanvasRenderCmd.js index 5be88269f2..e69de29bb2 100644 --- a/cocos2d/shape-nodes/CCDrawNodeCanvasRenderCmd.js +++ b/cocos2d/shape-nodes/CCDrawNodeCanvasRenderCmd.js @@ -1,131 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -(function(){ - - cc.DrawNode.CanvasRenderCmd = function(renderableObject){ - cc.Node.CanvasRenderCmd.call(this, renderableObject); - this._needDraw = true; - this._buffer = null; - this._drawColor = null; - this._blendFunc = null; - }; - - cc.DrawNode.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype); - cc.DrawNode.CanvasRenderCmd.prototype.constructor = cc.DrawNode.CanvasRenderCmd; - cc.extend( cc.DrawNode.CanvasRenderCmd.prototype, { - rendering: function (ctx, scaleX, scaleY) { - var wrapper = ctx || cc._renderContext, context = wrapper.getContext(), node = this._node; - var alpha = node._displayedOpacity / 255; - if (alpha === 0) - return; - - wrapper.setTransform(this._worldTransform, scaleX, scaleY); - - //context.save(); - wrapper.setGlobalAlpha(alpha); - if ((this._blendFunc && (this._blendFunc.src === cc.SRC_ALPHA) && (this._blendFunc.dst === cc.ONE))) - wrapper.setCompositeOperation('lighter'); //todo: need refactor - var locBuffer = this._buffer; - for (var i = 0, len = locBuffer.length; i < len; i++) { - var element = locBuffer[i]; - switch (element.type) { - case cc.DrawNode.TYPE_DOT: - this._drawDot(wrapper, element, scaleX, scaleY); - break; - case cc.DrawNode.TYPE_SEGMENT: - this._drawSegment(wrapper, element, scaleX, scaleY); - break; - case cc.DrawNode.TYPE_POLY: - this._drawPoly(wrapper, element, scaleX, scaleY); - break; - } - } - //context.restore(); //todo It can be reserve - }, - - _drawDot: function (wrapper, element, scaleX, scaleY) { - var locColor = element.fillColor, locPos = element.verts[0], locRadius = element.lineWidth; - - var ctx = wrapper.getContext(); - wrapper.setFillStyle("rgba(" + (0 | locColor.r) + "," + (0 | locColor.g) + "," + (0 | locColor.b) + "," + locColor.a / 255 + ")"); - - ctx.beginPath(); - ctx.arc(locPos.x * scaleX, -locPos.y * scaleY, locRadius * scaleX, 0, Math.PI * 2, false); - ctx.closePath(); - ctx.fill(); - }, - - _drawSegment: function (wrapper, element, scaleX, scaleY) { - var locColor = element.lineColor; - var locFrom = element.verts[0], locTo = element.verts[1]; - var locLineWidth = element.lineWidth, locLineCap = element.lineCap; - - var ctx = wrapper.getContext(); - wrapper.setStrokeStyle("rgba(" + (0 | locColor.r) + "," + (0 | locColor.g) + "," + (0 | locColor.b) + "," + locColor.a / 255 + ")"); - - ctx.lineWidth = locLineWidth * scaleX; - ctx.beginPath(); - ctx.lineCap = locLineCap; - ctx.moveTo(locFrom.x * scaleX, -locFrom.y * scaleY); - ctx.lineTo(locTo.x * scaleX, -locTo.y * scaleY); - ctx.stroke(); - }, - - _drawPoly: function (wrapper, element, scaleX, scaleY) { - var locVertices = element.verts, locLineCap = element.lineCap; - if (locVertices == null) - return; - - var locFillColor = element.fillColor, locLineWidth = element.lineWidth; - var locLineColor = element.lineColor, locIsClosePolygon = element.isClosePolygon; - var locIsFill = element.isFill, locIsStroke = element.isStroke; - - var ctx = wrapper.getContext(); - var firstPoint = locVertices[0]; - ctx.lineCap = locLineCap; - if (locFillColor) - wrapper.setFillStyle("rgba(" + (0 | locFillColor.r) + "," + (0 | locFillColor.g) + "," - + (0 | locFillColor.b) + "," + locFillColor.a / 255 + ")"); - if (locLineWidth) - ctx.lineWidth = locLineWidth * scaleX; - if (locLineColor) - wrapper.setStrokeStyle("rgba(" + (0 | locLineColor.r) + "," + (0 | locLineColor.g) + "," - + (0 | locLineColor.b) + "," + locLineColor.a / 255 + ")"); - - ctx.beginPath(); - ctx.moveTo(firstPoint.x * scaleX, -firstPoint.y * scaleY); - for (var i = 1, len = locVertices.length; i < len; i++) - ctx.lineTo(locVertices[i].x * scaleX, -locVertices[i].y * scaleY); - - if (locIsClosePolygon) - ctx.closePath(); - if (locIsFill) - ctx.fill(); - if (locIsStroke) - ctx.stroke(); - } - }); - -})(); diff --git a/cocos2d/text-input/CCTextFieldTTF.js b/cocos2d/text-input/CCTextFieldTTF.js index 716a85fbd9..e59dcb3515 100644 --- a/cocos2d/text-input/CCTextFieldTTF.js +++ b/cocos2d/text-input/CCTextFieldTTF.js @@ -257,8 +257,6 @@ cc.TextFieldTTF = cc.LabelTTF.extend(/** @lends cc.TextFieldTTF# */{ cc.LabelTTF.prototype.setString.call(this,this._inputText); this.setColor(this._colorText); } - if(cc._renderType === cc.game.RENDER_TYPE_CANVAS) - this._renderCmd._updateTexture(); this._charCount = this._inputText.length; }, diff --git a/cocos2d/tilemap/CCTMXLayer.js b/cocos2d/tilemap/CCTMXLayer.js index a2877df2c3..e69de29bb2 100644 --- a/cocos2d/tilemap/CCTMXLayer.js +++ b/cocos2d/tilemap/CCTMXLayer.js @@ -1,914 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -/** - *

cc.TMXLayer represents the TMX layer.

- * - *

It is a subclass of cc.SpriteBatchNode. By default the tiles are rendered using a cc.TextureAtlas.
- * If you modify a tile on runtime, then, that tile will become a cc.Sprite, otherwise no cc.Sprite objects are created.
- * The benefits of using cc.Sprite objects as tiles are:
- * - tiles (cc.Sprite) can be rotated/scaled/moved with a nice API

- * - *

If the layer contains a property named "cc.vertexz" with an integer (in can be positive or negative),
- * then all the tiles belonging to the layer will use that value as their OpenGL vertex Z for depth.

- * - *

On the other hand, if the "cc.vertexz" property has the "automatic" value, then the tiles will use an automatic vertex Z value.
- * Also before drawing the tiles, GL_ALPHA_TEST will be enabled, and disabled after drawing them. The used alpha func will be:

- * - * glAlphaFunc( GL_GREATER, value )
- * - *

"value" by default is 0, but you can change it from Tiled by adding the "cc_alpha_func" property to the layer.
- * The value 0 should work for most cases, but if you have tiles that are semi-transparent, then you might want to use a different value, like 0.5.

- * @class - * @extends cc.SpriteBatchNode - * - * @property {Array} tiles - Tiles for layer - * @property {cc.TMXTilesetInfo} tileset - Tileset for layer - * @property {Number} layerOrientation - Layer orientation - * @property {Array} properties - Properties from the layer. They can be added using tilemap editors - * @property {String} layerName - Name of the layer - * @property {Number} layerWidth - Width of the layer - * @property {Number} layerHeight - Height of the layer - * @property {Number} tileWidth - Width of a tile - * @property {Number} tileHeight - Height of a tile - */ -cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{ - tiles: null, - tileset: null, - layerOrientation: null, - properties: null, - layerName: "", - - //size of the layer in tiles - _layerSize: null, - _mapTileSize: null, - //TMX Layer supports opacity - _opacity: 255, - _minGID: null, - _maxGID: null, - //Only used when vertexZ is used - _vertexZvalue: null, - _useAutomaticVertexZ: null, - //used for optimization - _reusedTile: null, - _atlasIndexArray: null, - //used for retina display - _contentScaleFactor: null, - - _className:"TMXLayer", - - /** - * Creates a cc.TMXLayer with an tile set info, a layer info and a map info
- * Constructor of cc.TMXLayer - * @param {cc.TMXTilesetInfo} tilesetInfo - * @param {cc.TMXLayerInfo} layerInfo - * @param {cc.TMXMapInfo} mapInfo - */ - ctor:function (tilesetInfo, layerInfo, mapInfo) { - cc.SpriteBatchNode.prototype.ctor.call(this); - this._descendants = []; - - this._layerSize = cc.size(0, 0); - this._mapTileSize = cc.size(0, 0); - - if(mapInfo !== undefined) - this.initWithTilesetInfo(tilesetInfo, layerInfo, mapInfo); - }, - - _createRenderCmd: function(){ - if(cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new cc.TMXLayer.CanvasRenderCmd(this); - else - return new cc.TMXLayer.WebGLRenderCmd(this); - }, - - /** - * Sets the untransformed size of the TMXLayer. - * @override - * @param {cc.Size|Number} size The untransformed size of the TMXLayer or The untransformed size's width of the TMXLayer. - * @param {Number} [height] The untransformed size's height of the TMXLayer. - */ - setContentSize:function (size, height) { - cc.Node.prototype.setContentSize.call(this, size, height); - this._renderCmd._updateCacheContext(size, height); - }, - - /** - * Return texture of cc.SpriteBatchNode - * @function - * @return {cc.Texture2D} - */ - getTexture: function(){ - return this._renderCmd.getTexture(); - }, - - /** - * Gets layer size. - * @return {cc.Size} - */ - getLayerSize:function () { - return cc.size(this._layerSize.width, this._layerSize.height); - }, - - /** - * Set layer size - * @param {cc.Size} Var - */ - setLayerSize:function (Var) { - this._layerSize.width = Var.width; - this._layerSize.height = Var.height; - }, - - _getLayerWidth: function () { - return this._layerSize.width; - }, - _setLayerWidth: function (width) { - this._layerSize.width = width; - }, - _getLayerHeight: function () { - return this._layerSize.height; - }, - _setLayerHeight: function (height) { - this._layerSize.height = height; - }, - - /** - * Size of the map's tile (could be different from the tile's size) - * @return {cc.Size} - */ - getMapTileSize:function () { - return cc.size(this._mapTileSize.width,this._mapTileSize.height); - }, - - /** - * Set the map tile size. - * @param {cc.Size} Var - */ - setMapTileSize:function (Var) { - this._mapTileSize.width = Var.width; - this._mapTileSize.height = Var.height; - }, - - _getTileWidth: function () { - return this._mapTileSize.width; - }, - _setTileWidth: function (width) { - this._mapTileSize.width = width; - }, - _getTileHeight: function () { - return this._mapTileSize.height; - }, - _setTileHeight: function (height) { - this._mapTileSize.height = height; - }, - - /** - * Pointer to the map of tiles - * @return {Array} - */ - getTiles:function () { - return this.tiles; - }, - - /** - * Pointer to the map of tiles - * @param {Array} Var - */ - setTiles:function (Var) { - this.tiles = Var; - }, - - /** - * Tile set information for the layer - * @return {cc.TMXTilesetInfo} - */ - getTileset:function () { - return this.tileset; - }, - - /** - * Tile set information for the layer - * @param {cc.TMXTilesetInfo} Var - */ - setTileset:function (Var) { - this.tileset = Var; - }, - - /** - * Layer orientation, which is the same as the map orientation - * @return {Number} - */ - getLayerOrientation:function () { - return this.layerOrientation; - }, - - /** - * Layer orientation, which is the same as the map orientation - * @param {Number} Var - */ - setLayerOrientation:function (Var) { - this.layerOrientation = Var; - }, - - /** - * properties from the layer. They can be added using Tiled - * @return {Array} - */ - getProperties:function () { - return this.properties; - }, - - /** - * properties from the layer. They can be added using Tiled - * @param {Array} Var - */ - setProperties:function (Var) { - this.properties = Var; - }, - - /** - * Initializes a cc.TMXLayer with a tileset info, a layer info and a map info - * @param {cc.TMXTilesetInfo} tilesetInfo - * @param {cc.TMXLayerInfo} layerInfo - * @param {cc.TMXMapInfo} mapInfo - * @return {Boolean} - */ - initWithTilesetInfo:function (tilesetInfo, layerInfo, mapInfo) { - // XXX: is 35% a good estimate ? - var size = layerInfo._layerSize; - var totalNumberOfTiles = parseInt(size.width * size.height); - var capacity = totalNumberOfTiles * 0.35 + 1; // 35 percent is occupied ? - var texture; - if (tilesetInfo) - texture = cc.textureCache.addImage(tilesetInfo.sourceImage); - - if (this.initWithTexture(texture, capacity)) { - // layerInfo - this.layerName = layerInfo.name; - this._layerSize = size; - this.tiles = layerInfo._tiles; - this._minGID = layerInfo._minGID; - this._maxGID = layerInfo._maxGID; - this._opacity = layerInfo._opacity; - this.properties = layerInfo.properties; - this._contentScaleFactor = cc.director.getContentScaleFactor(); - - // tilesetInfo - this.tileset = tilesetInfo; - - // mapInfo - this._mapTileSize = mapInfo.getTileSize(); - this.layerOrientation = mapInfo.orientation; - - // offset (after layer orientation is set); - var offset = this._calculateLayerOffset(layerInfo.offset); - this.setPosition(cc.pointPixelsToPoints(offset)); - - this._atlasIndexArray = []; - this.setContentSize(cc.sizePixelsToPoints(cc.size(this._layerSize.width * this._mapTileSize.width, - this._layerSize.height * this._mapTileSize.height))); - this._useAutomaticVertexZ = false; - this._vertexZvalue = 0; - return true; - } - return false; - }, - - /** - *

Dealloc the map that contains the tile position from memory.
- * Unless you want to know at runtime the tiles positions, you can safely call this method.
- * If you are going to call layer.getTileGIDAt() then, don't release the map

- */ - releaseMap:function () { - if (this.tiles) - this.tiles = null; - - if (this._atlasIndexArray) - this._atlasIndexArray = null; - }, - - /** - *

Returns the tile (cc.Sprite) at a given a tile coordinate.
- * The returned cc.Sprite will be already added to the cc.TMXLayer. Don't add it again.
- * The cc.Sprite can be treated like any other cc.Sprite: rotated, scaled, translated, opacity, color, etc.
- * You can remove either by calling:
- * - layer.removeChild(sprite, cleanup);
- * - or layer.removeTileAt(ccp(x,y));

- * @param {cc.Point|Number} pos or x - * @param {Number} [y] - * @return {cc.Sprite} - */ - getTileAt: function (pos, y) { - if(!pos) - throw new Error("cc.TMXLayer.getTileAt(): pos should be non-null"); - if(y !== undefined) - pos = cc.p(pos, y); - if(pos.x >= this._layerSize.width || pos.y >= this._layerSize.height || pos.x < 0 || pos.y < 0) - throw new Error("cc.TMXLayer.getTileAt(): invalid position"); - if(!this.tiles || !this._atlasIndexArray){ - cc.log("cc.TMXLayer.getTileAt(): TMXLayer: the tiles map has been released"); - return null; - } - - var tile = null, gid = this.getTileGIDAt(pos); - - // if GID == 0, then no tile is present - if (gid === 0) - return tile; - - var z = 0 | (pos.x + pos.y * this._layerSize.width); - tile = this.getChildByTag(z); - // tile not created yet. create it - if (!tile) { - var rect = this.tileset.rectForGID(gid); - rect = cc.rectPixelsToPoints(rect); - - tile = new cc.Sprite(); - tile.initWithTexture(this.texture, rect); - tile.batchNode = this; - tile.setPosition(this.getPositionAt(pos)); - tile.vertexZ = this._vertexZForPos(pos); - tile.anchorX = 0; - tile.anchorY = 0; - tile.opacity = this._opacity; - - var indexForZ = this._atlasIndexForExistantZ(z); - this.addSpriteWithoutQuad(tile, indexForZ, z); - } - return tile; - }, - - /** - * Returns the tile gid at a given tile coordinate.
- * if it returns 0, it means that the tile is empty.
- * This method requires the the tile map has not been previously released (eg. don't call layer.releaseMap())
- * @param {cc.Point|Number} pos or x - * @param {Number} [y] - * @return {Number} - */ - getTileGIDAt:function (pos, y) { - if(pos == null) - throw new Error("cc.TMXLayer.getTileGIDAt(): pos should be non-null"); - if(y !== undefined) - pos = cc.p(pos, y); - if(pos.x >= this._layerSize.width || pos.y >= this._layerSize.height || pos.x < 0 || pos.y < 0) - throw new Error("cc.TMXLayer.getTileGIDAt(): invalid position"); - if(!this.tiles || !this._atlasIndexArray){ - cc.log("cc.TMXLayer.getTileGIDAt(): TMXLayer: the tiles map has been released"); - return null; - } - - var idx = 0 | (pos.x + pos.y * this._layerSize.width); - // Bits on the far end of the 32-bit global tile ID are used for tile flags - var tile = this.tiles[idx]; - - return (tile & cc.TMX_TILE_FLIPPED_MASK) >>> 0; - }, - // XXX: deprecated - // tileGIDAt:getTileGIDAt, - - /** - * lipped tiles can be changed dynamically - * @param {cc.Point|Number} pos or x - * @param {Number} [y] - * @return {Number} - */ - getTileFlagsAt:function (pos, y) { - if(!pos) - throw new Error("cc.TMXLayer.getTileFlagsAt(): pos should be non-null"); - if(y !== undefined) - pos = cc.p(pos, y); - if(pos.x >= this._layerSize.width || pos.y >= this._layerSize.height || pos.x < 0 || pos.y < 0) - throw new Error("cc.TMXLayer.getTileFlagsAt(): invalid position"); - if(!this.tiles || !this._atlasIndexArray){ - cc.log("cc.TMXLayer.getTileFlagsAt(): TMXLayer: the tiles map has been released"); - return null; - } - - var idx = 0 | (pos.x + pos.y * this._layerSize.width); - // Bits on the far end of the 32-bit global tile ID are used for tile flags - var tile = this.tiles[idx]; - - return (tile & cc.TMX_TILE_FLIPPED_ALL) >>> 0; - }, - // XXX: deprecated - // tileFlagAt:getTileFlagsAt, - - /** - *

Sets the tile gid (gid = tile global id) at a given tile coordinate.
- * The Tile GID can be obtained by using the method "tileGIDAt" or by using the TMX editor . Tileset Mgr +1.
- * If a tile is already placed at that position, then it will be removed.

- * @param {Number} gid - * @param {cc.Point|Number} posOrX position or x - * @param {Number} flagsOrY flags or y - * @param {Number} [flags] - */ - setTileGID: function(gid, posOrX, flagsOrY, flags) { - if(!posOrX) - throw new Error("cc.TMXLayer.setTileGID(): pos should be non-null"); - var pos; - if (flags !== undefined) { - pos = cc.p(posOrX, flagsOrY); - } else { - pos = posOrX; - flags = flagsOrY; - } - if(pos.x >= this._layerSize.width || pos.y >= this._layerSize.height || pos.x < 0 || pos.y < 0) - throw new Error("cc.TMXLayer.setTileGID(): invalid position"); - if(!this.tiles || !this._atlasIndexArray){ - cc.log("cc.TMXLayer.setTileGID(): TMXLayer: the tiles map has been released"); - return; - } - if(gid !== 0 && gid < this.tileset.firstGid){ - cc.log( "cc.TMXLayer.setTileGID(): invalid gid:" + gid); - return; - } - - flags = flags || 0; - this._setNodeDirtyForCache(); - var currentFlags = this.getTileFlagsAt(pos); - var currentGID = this.getTileGIDAt(pos); - - if (currentGID !== gid || currentFlags !== flags) { - var gidAndFlags = (gid | flags) >>> 0; - // setting gid=0 is equal to remove the tile - if (gid === 0) - this.removeTileAt(pos); - else if (currentGID === 0) // empty tile. create a new one - this._insertTileForGID(gidAndFlags, pos); - else { // modifying an existing tile with a non-empty tile - var z = pos.x + pos.y * this._layerSize.width; - var sprite = this.getChildByTag(z); - if (sprite) { - var rect = this.tileset.rectForGID(gid); - rect = cc.rectPixelsToPoints(rect); - - sprite.setTextureRect(rect, false); - if (flags != null) - this._setupTileSprite(sprite, pos, gidAndFlags); - - this.tiles[z] = gidAndFlags; - } else - this._updateTileForGID(gidAndFlags, pos); - } - } - }, - - /** - * Removes a tile at given tile coordinate - * @param {cc.Point|Number} pos position or x - * @param {Number} [y] - */ - removeTileAt:function (pos, y) { - if(!pos) - throw new Error("cc.TMXLayer.removeTileAt(): pos should be non-null"); - if(y !== undefined) - pos = cc.p(pos, y); - if(pos.x >= this._layerSize.width || pos.y >= this._layerSize.height || pos.x < 0 || pos.y < 0) - throw new Error("cc.TMXLayer.removeTileAt(): invalid position"); - if(!this.tiles || !this._atlasIndexArray){ - cc.log("cc.TMXLayer.removeTileAt(): TMXLayer: the tiles map has been released"); - return; - } - - var gid = this.getTileGIDAt(pos); - if (gid !== 0) { - if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) - this._setNodeDirtyForCache(); - var z = 0 | (pos.x + pos.y * this._layerSize.width); - var atlasIndex = this._atlasIndexForExistantZ(z); - // remove tile from GID map - this.tiles[z] = 0; - - // remove tile from atlas position array - this._atlasIndexArray.splice(atlasIndex, 1); - - // remove it from sprites and/or texture atlas - var sprite = this.getChildByTag(z); - - if (sprite) - cc.SpriteBatchNode.prototype.removeChild.call(this, sprite, true); //this.removeChild(sprite, true); - else { - if(cc._renderType === cc.game.RENDER_TYPE_WEBGL) - this.textureAtlas.removeQuadAtIndex(atlasIndex); - - // update possible children - if (this._children) { - var locChildren = this._children; - for (var i = 0, len = locChildren.length; i < len; i++) { - var child = locChildren[i]; - if (child) { - var ai = child.atlasIndex; - if (ai >= atlasIndex) - child.atlasIndex = ai - 1; - } - } - } - } - } - }, - - /** - * Returns the position in pixels of a given tile coordinate - * @param {cc.Point|Number} pos position or x - * @param {Number} [y] - * @return {cc.Point} - */ - getPositionAt:function (pos, y) { - if (y !== undefined) - pos = cc.p(pos, y); - var ret = cc.p(0,0); - switch (this.layerOrientation) { - case cc.TMX_ORIENTATION_ORTHO: - ret = this._positionForOrthoAt(pos); - break; - case cc.TMX_ORIENTATION_ISO: - ret = this._positionForIsoAt(pos); - break; - case cc.TMX_ORIENTATION_HEX: - ret = this._positionForHexAt(pos); - break; - } - return cc.pointPixelsToPoints(ret); - }, - // XXX: Deprecated. For backward compatibility only - // positionAt:getPositionAt, - - /** - * Return the value for the specific property name - * @param {String} propertyName - * @return {*} - */ - getProperty:function (propertyName) { - return this.properties[propertyName]; - }, - - /** - * Creates the tiles - */ - setupTiles:function () { - // Optimization: quick hack that sets the image size on the tileset - this._renderCmd.initImageSize(); - - // Parse cocos2d properties - this._parseInternalProperties(); - if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) - this._setNodeDirtyForCache(); - - var locLayerHeight = this._layerSize.height, locLayerWidth = this._layerSize.width; - for (var y = 0; y < locLayerHeight; y++) { - for (var x = 0; x < locLayerWidth; x++) { - var pos = x + locLayerWidth * y; - var gid = this.tiles[pos]; - - // XXX: gid == 0 -. empty tile - if (gid !== 0) { - this._appendTileForGID(gid, cc.p(x, y)); - // Optimization: update min and max GID rendered by the layer - this._minGID = Math.min(gid, this._minGID); - this._maxGID = Math.max(gid, this._maxGID); - } - } - } - - if (!((this._maxGID >= this.tileset.firstGid) && (this._minGID >= this.tileset.firstGid))) { - cc.log("cocos2d:TMX: Only 1 tileset per layer is supported"); - } - }, - - /** - * cc.TMXLayer doesn't support adding a cc.Sprite manually. - * @warning addChild(child); is not supported on cc.TMXLayer. Instead of setTileGID. - * @param {cc.Node} child - * @param {number} zOrder - * @param {number} tag - */ - addChild:function (child, zOrder, tag) { - cc.log("addChild: is not supported on cc.TMXLayer. Instead use setTileGID or tileAt."); - }, - - /** - * Remove child - * @param {cc.Sprite} sprite - * @param {Boolean} cleanup - */ - removeChild:function (sprite, cleanup) { - // allows removing nil objects - if (!sprite) - return; - - if(this._children.indexOf(sprite) === -1){ - cc.log("cc.TMXLayer.removeChild(): Tile does not belong to TMXLayer"); - return; - } - - if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) - this._setNodeDirtyForCache(); - var atlasIndex = sprite.atlasIndex; - var zz = this._atlasIndexArray[atlasIndex]; - this.tiles[zz] = 0; - this._atlasIndexArray.splice(atlasIndex, 1); - cc.SpriteBatchNode.prototype.removeChild.call(this, sprite, cleanup); - cc.renderer.childrenOrderDirty = true; - }, - - /** - * Gets the layer name - * @return {String} - */ - getLayerName:function () { - return this.layerName; - }, - - /** - * Set the layer name - * @param {String} layerName - */ - setLayerName:function (layerName) { - this.layerName = layerName; - }, - - _positionForIsoAt:function (pos) { - return cc.p(this._mapTileSize.width / 2 * ( this._layerSize.width + pos.x - pos.y - 1), - this._mapTileSize.height / 2 * (( this._layerSize.height * 2 - pos.x - pos.y) - 2)); - }, - - _positionForOrthoAt:function (pos) { - return cc.p(pos.x * this._mapTileSize.width, - (this._layerSize.height - pos.y - 1) * this._mapTileSize.height); - }, - - _positionForHexAt:function (pos) { - var diffY = (pos.x % 2 === 1) ? (-this._mapTileSize.height / 2) : 0; - return cc.p(pos.x * this._mapTileSize.width * 3 / 4, - (this._layerSize.height - pos.y - 1) * this._mapTileSize.height + diffY); - }, - - _calculateLayerOffset:function (pos) { - var ret = cc.p(0,0); - switch (this.layerOrientation) { - case cc.TMX_ORIENTATION_ORTHO: - ret = cc.p(pos.x * this._mapTileSize.width, -pos.y * this._mapTileSize.height); - break; - case cc.TMX_ORIENTATION_ISO: - ret = cc.p((this._mapTileSize.width / 2) * (pos.x - pos.y), - (this._mapTileSize.height / 2 ) * (-pos.x - pos.y)); - break; - case cc.TMX_ORIENTATION_HEX: - if(pos.x !== 0 || pos.y !== 0) - cc.log("offset for hexagonal map not implemented yet"); - break; - } - return ret; - }, - - _appendTileForGID:function (gid, pos) { - var rect = this.tileset.rectForGID(gid); - rect = cc.rectPixelsToPoints(rect); - - var z = 0 | (pos.x + pos.y * this._layerSize.width); - var tile = this._renderCmd._reusedTileWithRect(rect); - this._setupTileSprite(tile, pos, gid); - - // optimization: - // The difference between appendTileForGID and insertTileforGID is that append is faster, since - // it appends the tile at the end of the texture atlas - var indexForZ = this._atlasIndexArray.length; - - // don't add it using the "standard" way. - this.insertQuadFromSprite(tile, indexForZ); - - // append should be after addQuadFromSprite since it modifies the quantity values - this._atlasIndexArray.splice(indexForZ, 0, z); - return tile; - }, - - _insertTileForGID:function (gid, pos) { - var rect = this.tileset.rectForGID(gid); - rect = cc.rectPixelsToPoints(rect); - - var z = 0 | (pos.x + pos.y * this._layerSize.width); - var tile = this._renderCmd._reusedTileWithRect(rect); - this._setupTileSprite(tile, pos, gid); - - // get atlas index - var indexForZ = this._atlasIndexForNewZ(z); - - // Optimization: add the quad without adding a child - this.insertQuadFromSprite(tile, indexForZ); - - // insert it into the local atlasindex array - this._atlasIndexArray.splice(indexForZ, 0, z); - // update possible children - if (this._children) { - var locChildren = this._children; - for (var i = 0, len = locChildren.length; i < len; i++) { - var child = locChildren[i]; - if (child) { - var ai = child.atlasIndex; - if (ai >= indexForZ) - child.atlasIndex = ai + 1; - } - } - } - this.tiles[z] = gid; - return tile; - }, - - _updateTileForGID:function (gid, pos) { - var rect = this.tileset.rectForGID(gid); - var locScaleFactor = this._contentScaleFactor; - rect = cc.rect(rect.x / locScaleFactor, rect.y / locScaleFactor, - rect.width / locScaleFactor, rect.height / locScaleFactor); - var z = pos.x + pos.y * this._layerSize.width; - - var tile = this._renderCmd._reusedTileWithRect(rect); - this._setupTileSprite(tile, pos, gid); - - // get atlas index - tile.atlasIndex = this._atlasIndexForExistantZ(z); - tile.dirty = true; - tile.updateTransform(); - this.tiles[z] = gid; - - return tile; - }, - - //The layer recognizes some special properties, like cc_vertez - _parseInternalProperties:function () { - // if cc_vertex=automatic, then tiles will be rendered using vertexz - var vertexz = this.getProperty("cc_vertexz"); - if (vertexz) { - if (vertexz === "automatic") { - this._useAutomaticVertexZ = true; - var alphaFuncVal = this.getProperty("cc_alpha_func"); - var alphaFuncValue = 0; - if (alphaFuncVal) - alphaFuncValue = parseFloat(alphaFuncVal); - - if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) { //todo: need move to WebGL render cmd - this.shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLORALPHATEST); - var alphaValueLocation = cc._renderContext.getUniformLocation(this.shaderProgram.getProgram(), cc.UNIFORM_ALPHA_TEST_VALUE_S); - // NOTE: alpha test shader is hard-coded to use the equivalent of a glAlphaFunc(GL_GREATER) comparison - this.shaderProgram.use(); - this.shaderProgram.setUniformLocationWith1f(alphaValueLocation, alphaFuncValue); - } - } else - this._vertexZvalue = parseInt(vertexz, 10); - } - }, - - _setupTileSprite:function (sprite, pos, gid) { - var z = pos.x + pos.y * this._layerSize.width; - sprite.setPosition(this.getPositionAt(pos)); - if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) - sprite.vertexZ = this._vertexZForPos(pos); - else - sprite.tag = z; - - sprite.anchorX = 0; - sprite.anchorY = 0; - sprite.opacity = this._opacity; - if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) { - sprite.rotation = 0.0; - } - - sprite.setFlippedX(false); - sprite.setFlippedY(false); - - // Rotation in tiled is achieved using 3 flipped states, flipping across the horizontal, vertical, and diagonal axes of the tiles. - if ((gid & cc.TMX_TILE_DIAGONAL_FLAG) >>> 0) { - // put the anchor in the middle for ease of rotation. - sprite.anchorX = 0.5; - sprite.anchorY = 0.5; - sprite.x = this.getPositionAt(pos).x + sprite.width / 2; - sprite.y = this.getPositionAt(pos).y + sprite.height / 2; - - var flag = (gid & (cc.TMX_TILE_HORIZONTAL_FLAG | cc.TMX_TILE_VERTICAL_FLAG) >>> 0) >>> 0; - // handle the 4 diagonally flipped states. - if (flag === cc.TMX_TILE_HORIZONTAL_FLAG) - sprite.rotation = 90; - else if (flag === cc.TMX_TILE_VERTICAL_FLAG) - sprite.rotation = 270; - else if (flag === (cc.TMX_TILE_VERTICAL_FLAG | cc.TMX_TILE_HORIZONTAL_FLAG) >>> 0) { - sprite.rotation = 90; - sprite.setFlippedX(true); - } else { - sprite.rotation = 270; - sprite.setFlippedX(true); - } - } else { - if ((gid & cc.TMX_TILE_HORIZONTAL_FLAG) >>> 0) { - sprite.setFlippedX(true); - } - - if ((gid & cc.TMX_TILE_VERTICAL_FLAG) >>> 0) { - sprite.setFlippedY(true); - } - } - }, - - _vertexZForPos:function (pos) { - var ret = 0; - var maxVal = 0; - if (this._useAutomaticVertexZ) { - switch (this.layerOrientation) { - case cc.TMX_ORIENTATION_ISO: - maxVal = this._layerSize.width + this._layerSize.height; - ret = -(maxVal - (pos.x + pos.y)); - break; - case cc.TMX_ORIENTATION_ORTHO: - ret = -(this._layerSize.height - pos.y); - break; - case cc.TMX_ORIENTATION_HEX: - cc.log("TMX Hexa zOrder not supported"); - break; - default: - cc.log("TMX invalid value"); - break; - } - } else - ret = this._vertexZvalue; - return ret; - }, - - _atlasIndexForExistantZ:function (z) { - var item; - if (this._atlasIndexArray) { - var locAtlasIndexArray = this._atlasIndexArray; - for (var i = 0, len = locAtlasIndexArray.length; i < len; i++) { - item = locAtlasIndexArray[i]; - if (item === z) - break; - } - } - if(!cc.isNumber(item)) - cc.log("cc.TMXLayer._atlasIndexForExistantZ(): TMX atlas index not found. Shall not happen"); - return i; - }, - - _atlasIndexForNewZ:function (z) { - var locAtlasIndexArray = this._atlasIndexArray; - for (var i = 0, len = locAtlasIndexArray.length; i < len; i++) { - var val = locAtlasIndexArray[i]; - if (z < val) - break; - } - return i; - } -}); - -var _p = cc.TMXLayer.prototype; - -/** @expose */ -cc.defineGetterSetter(_p, "texture", _p.getTexture, _p.setTexture); - -// Extended properties -/** @expose */ -_p.layerWidth; -cc.defineGetterSetter(_p, "layerWidth", _p._getLayerWidth, _p._setLayerWidth); -/** @expose */ -_p.layerHeight; -cc.defineGetterSetter(_p, "layerHeight", _p._getLayerHeight, _p._setLayerHeight); -/** @expose */ -_p.tileWidth; -cc.defineGetterSetter(_p, "tileWidth", _p._getTileWidth, _p._setTileWidth); -/** @expose */ -_p.tileHeight; -cc.defineGetterSetter(_p, "tileHeight", _p._getTileHeight, _p._setTileHeight); - - -/** - * Creates a cc.TMXLayer with an tile set info, a layer info and a map info - * @deprecated since v3.0 please use new cc.TMXLayer(tilesetInfo, layerInfo, mapInfo) instead. - * @param {cc.TMXTilesetInfo} tilesetInfo - * @param {cc.TMXLayerInfo} layerInfo - * @param {cc.TMXMapInfo} mapInfo - * @return {cc.TMXLayer|Null} - */ -cc.TMXLayer.create = function (tilesetInfo, layerInfo, mapInfo) { - return new cc.TMXLayer(tilesetInfo, layerInfo, mapInfo); -}; diff --git a/cocos2d/tilemap/CCTMXLayerCanvasRenderCmd.js b/cocos2d/tilemap/CCTMXLayerCanvasRenderCmd.js index 79a1ff197d..e69de29bb2 100644 --- a/cocos2d/tilemap/CCTMXLayerCanvasRenderCmd.js +++ b/cocos2d/tilemap/CCTMXLayerCanvasRenderCmd.js @@ -1,220 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -(function(){ - cc.TMXLayer.CanvasRenderCmd = function(renderable){ - cc.SpriteBatchNode.CanvasRenderCmd.call(this, renderable); - this._needDraw = true; - this._realWorldTransform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0}; - - var locCanvas = cc._canvas; - var tmpCanvas = document.createElement('canvas'); - tmpCanvas.width = locCanvas.width; - tmpCanvas.height = locCanvas.height; - this._cacheCanvas = tmpCanvas; - this._cacheContext = new cc.CanvasContextWrapper(this._cacheCanvas.getContext('2d')); - var tempTexture = new cc.Texture2D(); - tempTexture.initWithElement(tmpCanvas); - tempTexture.handleLoadedTexture(); - this._cacheTexture = tempTexture; - // This class uses cache, so its default cachedParent should be himself - this._cacheDirty = false; - }; - - var proto = cc.TMXLayer.CanvasRenderCmd.prototype = Object.create(cc.SpriteBatchNode.CanvasRenderCmd.prototype); - proto.constructor = cc.TMXLayer.CanvasRenderCmd; - - //set the cache dirty flag for canvas - proto._setNodeDirtyForCache = function () { - this._cacheDirty = true; - }; - - proto._renderingChildToCache = function () { - if (this._cacheDirty) { - var wrapper = this._cacheContext, - context = wrapper.getContext(), locCanvas = this._cacheCanvas; - - //wrapper.save(); - context.setTransform(1, 0, 0, 1, 0, 0); - context.clearRect(0, 0, locCanvas.width, locCanvas.height); - //reset the cache context - - var locChildren = this._node._children; - for (var i = 0, len = locChildren.length; i < len; i++) { - if (locChildren[i]){ - var selCmd = locChildren[i]._renderCmd; - if(selCmd){ - selCmd.rendering(wrapper, 1, 1); - selCmd._cacheDirty = false; - } - } - } - - //wrapper.restore(); - this._cacheDirty = false; - } - }; - - proto.rendering = function (ctx, scaleX, scaleY) { - var alpha = this._displayedOpacity / 255; - if (alpha <= 0) - return; - - var node = this._node; - this._renderingChildToCache(); - var wrapper = ctx || cc._renderContext, context = wrapper.getContext(); - wrapper.setGlobalAlpha(alpha); - - var locCacheCanvas = this._cacheCanvas; - //direct draw image by canvas drawImage - if (locCacheCanvas && locCacheCanvas.width !== 0 && locCacheCanvas.height !== 0) { - wrapper.setTransform(this._realWorldTransform, scaleX, scaleY); - var locCanvasHeight = locCacheCanvas.height * scaleY; - if (node.layerOrientation === cc.TMX_ORIENTATION_HEX) { - var halfTileSize = node._mapTileSize.height * 0.5 * scaleY; - context.drawImage(locCacheCanvas, 0, 0, locCacheCanvas.width, locCacheCanvas.height, - 0, -locCanvasHeight + halfTileSize, locCacheCanvas.width * scaleX, locCanvasHeight); - } else { - context.drawImage(locCacheCanvas, 0, 0, locCacheCanvas.width, locCacheCanvas.height, - 0, -locCanvasHeight, locCacheCanvas.width * scaleX, locCanvasHeight); - } - } - cc.g_NumberOfDraws++; - }; - - proto._updateCacheContext = function(size, height){ - var node = this._node, - locContentSize = node._contentSize, - locCanvas = this._cacheCanvas, - scaleFactor = cc.contentScaleFactor(); - locCanvas.width = 0 | (locContentSize.width * 1.5 * scaleFactor); - locCanvas.height = 0 | (locContentSize.height * 1.5 * scaleFactor); - - //todo: need change the wrapper's height - if(node.layerOrientation === cc.TMX_ORIENTATION_HEX) - this._cacheContext.setOffset(0, -node._mapTileSize.height * 0.5); //translate for hexagonal - else - this._cacheContext.setOffset(0, 0); - var locTexContentSize = this._cacheTexture._contentSize; - locTexContentSize.width = locCanvas.width; - locTexContentSize.height = locCanvas.height; - }; - - proto.getTexture = function(){ - return this._cacheTexture; - }; - - proto.visit = function(parentCmd){ - var node = this._node; - //TODO: it will implement dynamic compute child cutting automation. - var i, len, locChildren = node._children; - // quick return if not visible - if (!node._visible || !locChildren || locChildren.length === 0) - return; - - parentCmd = parentCmd || this.getParentRenderCmd(); - if (parentCmd) - this._curLevel = parentCmd._curLevel + 1; - - this._syncStatus(parentCmd); - if (this._cacheDirty) { - var wrapper = this._cacheContext, locCanvas = this._cacheCanvas, context = wrapper.getContext(), - instanceID = node.__instanceId, renderer = cc.renderer; - //begin cache - renderer._turnToCacheMode(instanceID); - - node.sortAllChildren(); - for (i = 0, len = locChildren.length; i < len; i++) { - if (locChildren[i]){ - var selCmd = locChildren[i]._renderCmd; - if(selCmd){ - selCmd.visit(this); - selCmd._cacheDirty = false; - } - } - } - - //wrapper.save(); - context.setTransform(1, 0, 0, 1, 0, 0); - context.clearRect(0, 0, locCanvas.width, locCanvas.height); - //set the wrapper's offset - - //draw to cache canvas - renderer._renderingToCacheCanvas(wrapper, instanceID); - //wrapper.restore(); //todo: it can be reserve. - this._cacheDirty = false - } - cc.renderer.pushRenderCommand(this); - this._dirtyFlag = 0; - }; - - proto.transform = function (parentCmd, recursive) { - // transform for canvas - var t = this.getNodeToParentTransform(), - worldT = this._realWorldTransform; //get the world transform - - if (parentCmd) { - var pt = parentCmd._worldTransform; - // cc.AffineTransformConcat is incorrect at get world transform - worldT.a = t.a * pt.a + t.b * pt.c; //a - worldT.b = t.a * pt.b + t.b * pt.d; //b - worldT.c = t.c * pt.a + t.d * pt.c; //c - worldT.d = t.c * pt.b + t.d * pt.d; //d - - worldT.tx = pt.a * t.tx + pt.c * t.ty + pt.tx; - worldT.ty = pt.d * t.ty + pt.ty + pt.b * t.tx; - } else { - worldT.a = t.a; - worldT.b = t.b; - worldT.c = t.c; - worldT.d = t.d; - worldT.tx = t.tx; - worldT.ty = t.ty; - } - if (recursive) { - var locChildren = this._node._children; - if (!locChildren || locChildren.length === 0) - return; - var i, len; - for (i = 0, len = locChildren.length; i < len; i++) { - locChildren[i]._renderCmd.transform(this, recursive); - } - } - }; - - proto.initImageSize = function(){ - var node = this._node; - node.tileset.imageSize = this._texture.getContentSizeInPixels(); - }; - - proto._reusedTileWithRect = function(rect){ - var node = this._node; - node._reusedTile = new cc.Sprite(); - node._reusedTile.initWithTexture(this._texture, rect, false); - node._reusedTile.batchNode = node; - node._reusedTile.parent = node; - node._reusedTile._renderCmd._cachedParent = node._renderCmd; - return node._reusedTile; - }; -})(); \ No newline at end of file diff --git a/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js b/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js index 8c1906f640..e69de29bb2 100644 --- a/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js +++ b/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js @@ -1,67 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -(function(){ - cc.TMXLayer.WebGLRenderCmd = function(renderableObject){ - cc.SpriteBatchNode.WebGLRenderCmd.call(this, renderableObject); - this._needDraw = true; - }; - - var proto = cc.TMXLayer.WebGLRenderCmd.prototype = Object.create(cc.SpriteBatchNode.WebGLRenderCmd.prototype); - proto.constructor = cc.TMXLayer.WebGLRenderCmd; - - proto._updateCacheContext = function(){}; - - proto.initImageSize = function(){ - var node = this._node; - node.tileset.imageSize = this._textureAtlas.texture.getContentSizeInPixels(); - - // By default all the tiles are aliased - // pros: - // - easier to render - // cons: - // - difficult to scale / rotate / etc. - this._textureAtlas.texture.setAliasTexParameters(); - }; - - proto._reusedTileWithRect = function(rect){ - var node = this._node; - if (!node._reusedTile) { - node._reusedTile = new cc.Sprite(); - node._reusedTile.initWithTexture(node.texture, rect, false); - node._reusedTile.batchNode = node; - } else { - // XXX HACK: Needed because if "batch node" is nil, - // then the Sprite'squad will be reset - node._reusedTile.batchNode = null; - - // Re-init the sprite - node._reusedTile.setTextureRect(rect, false); - - // restore the batch node - node._reusedTile.batchNode = node; - } - return node._reusedTile; - }; -})(); diff --git a/cocos2d/tilemap/CCTMXTiledMap.js b/cocos2d/tilemap/CCTMXTiledMap.js index fe14fa788f..e69de29bb2 100644 --- a/cocos2d/tilemap/CCTMXTiledMap.js +++ b/cocos2d/tilemap/CCTMXTiledMap.js @@ -1,479 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -/** - Orthogonal orientation - * @constant - * @type Number - */ -cc.TMX_ORIENTATION_ORTHO = 0; - -/** - * Hexagonal orientation - * @constant - * @type Number - */ - -cc.TMX_ORIENTATION_HEX = 1; - -/** - * Isometric orientation - * @constant - * @type Number - */ -cc.TMX_ORIENTATION_ISO = 2; - -/** - *

cc.TMXTiledMap knows how to parse and render a TMX map.

- * - *

It adds support for the TMX tiled map format used by http://www.mapeditor.org
- * It supports isometric, hexagonal and orthogonal tiles.
- * It also supports object groups, objects, and properties.

- * - *

Features:
- * - Each tile will be treated as an cc.Sprite
- * - The sprites are created on demand. They will be created only when you call "layer.getTileAt(position)"
- * - Each tile can be rotated / moved / scaled / tinted / "opacitied", since each tile is a cc.Sprite
- * - Tiles can be added/removed in runtime
- * - The z-order of the tiles can be modified in runtime
- * - Each tile has an anchorPoint of (0,0)
- * - The anchorPoint of the TMXTileMap is (0,0)
- * - The TMX layers will be added as a child
- * - The TMX layers will be aliased by default
- * - The tileset image will be loaded using the cc.TextureCache
- * - Each tile will have a unique tag
- * - Each tile will have a unique z value. top-left: z=1, bottom-right: z=max z
- * - Each object group will be treated as an cc.MutableArray
- * - Object class which will contain all the properties in a dictionary
- * - Properties can be assigned to the Map, Layer, Object Group, and Object

- * - *

Limitations:
- * - It only supports one tileset per layer.
- * - Embeded images are not supported
- * - It only supports the XML format (the JSON format is not supported)

- * - *

Technical description:
- * Each layer is created using an cc.TMXLayer (subclass of cc.SpriteBatchNode). If you have 5 layers, then 5 cc.TMXLayer will be created,
- * unless the layer visibility is off. In that case, the layer won't be created at all.
- * You can obtain the layers (cc.TMXLayer objects) at runtime by:
- * - map.getChildByTag(tag_number); // 0=1st layer, 1=2nd layer, 2=3rd layer, etc...
- * - map.getLayer(name_of_the_layer);

- * - *

Each object group is created using a cc.TMXObjectGroup which is a subclass of cc.MutableArray.
- * You can obtain the object groups at runtime by:
- * - map.getObjectGroup(name_of_the_object_group);

- * - *

Each object is a cc.TMXObject.

- * - *

Each property is stored as a key-value pair in an cc.MutableDictionary.
- * You can obtain the properties at runtime by:

- * - *

map.getProperty(name_of_the_property);
- * layer.getProperty(name_of_the_property);
- * objectGroup.getProperty(name_of_the_property);
- * object.getProperty(name_of_the_property);

- * @class - * @extends cc.Node - * @param {String} tmxFile tmxFile fileName or content string - * @param {String} resourcePath If tmxFile is a file name ,it is not required.If tmxFile is content string ,it is must required. - - * - * @property {Array} properties - Properties from the map. They can be added using tilemap editors - * @property {Number} mapOrientation - Map orientation - * @property {Array} objectGroups - Object groups of the map - * @property {Number} mapWidth - Width of the map - * @property {Number} mapHeight - Height of the map - * @property {Number} tileWidth - Width of a tile - * @property {Number} tileHeight - Height of a tile - * - * @example - * //example - * 1. - * //create a TMXTiledMap with file name - * var tmxTiledMap = new cc.TMXTiledMap("res/orthogonal-test1.tmx"); - * 2. - * //create a TMXTiledMap with content string and resource path - * var resources = "res/TileMaps"; - * var filePath = "res/TileMaps/orthogonal-test1.tmx"; - * var xmlStr = cc.loader.getRes(filePath); - * var tmxTiledMap = new cc.TMXTiledMap(xmlStr, resources); - */ -cc.TMXTiledMap = cc.Node.extend(/** @lends cc.TMXTiledMap# */{ - properties: null, - mapOrientation: null, - objectGroups: null, - - //the map's size property measured in tiles - _mapSize: null, - _tileSize: null, - //tile properties - _tileProperties: null, - _className: "TMXTiledMap", - - /** - * Creates a TMX Tiled Map with a TMX file or content string.
- * Constructor of cc.TMXTiledMap - * @param {String} tmxFile tmxFile fileName or content string - * @param {String} resourcePath If tmxFile is a file name ,it is not required.If tmxFile is content string ,it is must required. - */ - ctor:function(tmxFile,resourcePath){ - cc.Node.prototype.ctor.call(this); - this._mapSize = cc.size(0, 0); - this._tileSize = cc.size(0, 0); - - if(resourcePath !== undefined){ - this.initWithXML(tmxFile,resourcePath); - }else if(tmxFile !== undefined){ - this.initWithTMXFile(tmxFile); - } - }, - - /** - * Gets the map size. - * @return {cc.Size} - */ - getMapSize:function () { - return cc.size(this._mapSize.width, this._mapSize.height); - }, - - /** - * Set the map size. - * @param {cc.Size} Var - */ - setMapSize:function (Var) { - this._mapSize.width = Var.width; - this._mapSize.height = Var.height; - }, - - _getMapWidth: function () { - return this._mapSize.width; - }, - _setMapWidth: function (width) { - this._mapSize.width = width; - }, - _getMapHeight: function () { - return this._mapSize.height; - }, - _setMapHeight: function (height) { - this._mapSize.height = height; - }, - - /** - * Gets the tile size. - * @return {cc.Size} - */ - getTileSize:function () { - return cc.size(this._tileSize.width, this._tileSize.height); - }, - - /** - * Set the tile size - * @param {cc.Size} Var - */ - setTileSize:function (Var) { - this._tileSize.width = Var.width; - this._tileSize.height = Var.height; - }, - - _getTileWidth: function () { - return this._tileSize.width; - }, - _setTileWidth: function (width) { - this._tileSize.width = width; - }, - _getTileHeight: function () { - return this._tileSize.height; - }, - _setTileHeight: function (height) { - this._tileSize.height = height; - }, - - /** - * map orientation - * @return {Number} - */ - getMapOrientation:function () { - return this.mapOrientation; - }, - - /** - * map orientation - * @param {Number} Var - */ - setMapOrientation:function (Var) { - this.mapOrientation = Var; - }, - - /** - * object groups - * @return {Array} - */ - getObjectGroups:function () { - return this.objectGroups; - }, - - /** - * object groups - * @param {Array} Var - */ - setObjectGroups:function (Var) { - this.objectGroups = Var; - }, - - /** - * Gets the properties - * @return {object} - */ - getProperties:function () { - return this.properties; - }, - - /** - * Set the properties - * @param {object} Var - */ - setProperties:function (Var) { - this.properties = Var; - }, - - /** - * Initializes the instance of cc.TMXTiledMap with tmxFile - * @param {String} tmxFile - * @return {Boolean} Whether the initialization was successful. - * @example - * //example - * var map = new cc.TMXTiledMap() - * map.initWithTMXFile("hello.tmx"); - */ - initWithTMXFile:function (tmxFile) { - if(!tmxFile || tmxFile.length === 0) - throw new Error("cc.TMXTiledMap.initWithTMXFile(): tmxFile should be non-null or non-empty string."); - this.width = 0; - this.height = 0; - var mapInfo = new cc.TMXMapInfo(tmxFile); - if (!mapInfo) - return false; - - var locTilesets = mapInfo.getTilesets(); - if(!locTilesets || locTilesets.length === 0) - cc.log("cc.TMXTiledMap.initWithTMXFile(): Map not found. Please check the filename."); - this._buildWithMapInfo(mapInfo); - return true; - }, - - /** - * Initializes the instance of cc.TMXTiledMap with tmxString - * @param {String} tmxString - * @param {String} resourcePath - * @return {Boolean} Whether the initialization was successful. - */ - initWithXML:function(tmxString, resourcePath){ - this.width = 0; - this.height = 0; - - var mapInfo = new cc.TMXMapInfo(tmxString, resourcePath); - var locTilesets = mapInfo.getTilesets(); - if(!locTilesets || locTilesets.length === 0) - cc.log("cc.TMXTiledMap.initWithXML(): Map not found. Please check the filename."); - this._buildWithMapInfo(mapInfo); - return true; - }, - - _buildWithMapInfo:function (mapInfo) { - this._mapSize = mapInfo.getMapSize(); - this._tileSize = mapInfo.getTileSize(); - this.mapOrientation = mapInfo.orientation; - this.objectGroups = mapInfo.getObjectGroups(); - this.properties = mapInfo.properties; - this._tileProperties = mapInfo.getTileProperties(); - - var idx = 0; - var layers = mapInfo.getLayers(); - if (layers) { - var layerInfo = null; - for (var i = 0, len = layers.length; i < len; i++) { - layerInfo = layers[i]; - if (layerInfo && layerInfo.visible) { - var child = this._parseLayer(layerInfo, mapInfo); - this.addChild(child, idx, idx); - // update content size with the max size - this.width = Math.max(this.width, child.width); - this.height = Math.max(this.height, child.height); - idx++; - } - } - } - }, - - /** - * Return All layers array. - * @returns {Array} - */ - allLayers: function () { - var retArr = [], locChildren = this._children; - for(var i = 0, len = locChildren.length;i< len;i++){ - var layer = locChildren[i]; - if(layer && layer instanceof cc.TMXLayer) - retArr.push(layer); - } - return retArr; - }, - - /** - * return the TMXLayer for the specific layer - * @param {String} layerName - * @return {cc.TMXLayer} - */ - getLayer:function (layerName) { - if(!layerName || layerName.length === 0) - throw new Error("cc.TMXTiledMap.getLayer(): layerName should be non-null or non-empty string."); - var locChildren = this._children; - for (var i = 0; i < locChildren.length; i++) { - var layer = locChildren[i]; - if (layer && layer.layerName === layerName) - return layer; - } - // layer not found - return null; - }, - - /** - * Return the TMXObjectGroup for the specific group - * @param {String} groupName - * @return {cc.TMXObjectGroup} - */ - getObjectGroup:function (groupName) { - if(!groupName || groupName.length === 0) - throw new Error("cc.TMXTiledMap.getObjectGroup(): groupName should be non-null or non-empty string."); - if (this.objectGroups) { - for (var i = 0; i < this.objectGroups.length; i++) { - var objectGroup = this.objectGroups[i]; - if (objectGroup && objectGroup.groupName === groupName) { - return objectGroup; - } - } - } - // objectGroup not found - return null; - }, - - /** - * Return the value for the specific property name - * @param {String} propertyName - * @return {String} - */ - getProperty:function (propertyName) { - return this.properties[propertyName.toString()]; - }, - - /** - * Return properties dictionary for tile GID - * @param {Number} GID - * @return {object} - * @deprecated - */ - propertiesForGID:function (GID) { - cc.log("propertiesForGID is deprecated. Please use getPropertiesForGID instead."); - return this.getPropertiesForGID[GID]; - }, - - /** - * Return properties dictionary for tile GID - * @param {Number} GID - * @return {object} - */ - getPropertiesForGID: function(GID) { - return this._tileProperties[GID]; - }, - - _parseLayer:function (layerInfo, mapInfo) { - var tileset = this._tilesetForLayer(layerInfo, mapInfo); - var layer = new cc.TMXLayer(tileset, layerInfo, mapInfo); - // tell the layerinfo to release the ownership of the tiles map. - layerInfo.ownTiles = false; - layer.setupTiles(); - return layer; - }, - - _tilesetForLayer:function (layerInfo, mapInfo) { - var size = layerInfo._layerSize; - var tilesets = mapInfo.getTilesets(); - if (tilesets) { - for (var i = tilesets.length - 1; i >= 0; i--) { - var tileset = tilesets[i]; - if (tileset) { - for (var y = 0; y < size.height; y++) { - for (var x = 0; x < size.width; x++) { - var pos = x + size.width * y; - var gid = layerInfo._tiles[pos]; - if (gid !== 0) { - // Optimization: quick return - // if the layer is invalid (more than 1 tileset per layer) an cc.assert will be thrown later - if (((gid & cc.TMX_TILE_FLIPPED_MASK)>>>0) >= tileset.firstGid) { - return tileset; - } - } - - } - } - } - } - } - - // If all the tiles are 0, return empty tileset - cc.log("cocos2d: Warning: TMX Layer " + layerInfo.name + " has no tiles"); - return null; - } -}); - -var _p = cc.TMXTiledMap.prototype; - -// Extended properties -/** @expose */ -_p.mapWidth; -cc.defineGetterSetter(_p, "mapWidth", _p._getMapWidth, _p._setMapWidth); -/** @expose */ -_p.mapHeight; -cc.defineGetterSetter(_p, "mapHeight", _p._getMapHeight, _p._setMapHeight); -/** @expose */ -_p.tileWidth; -cc.defineGetterSetter(_p, "tileWidth", _p._getTileWidth, _p._setTileWidth); -/** @expose */ -_p.tileHeight; -cc.defineGetterSetter(_p, "tileHeight", _p._getTileHeight, _p._setTileHeight); - - -/** - * Creates a TMX Tiled Map with a TMX file or content string. - * Implementation cc.TMXTiledMap - * @deprecated since v3.0 please use new cc.TMXTiledMap(tmxFile,resourcePath) instead. - * @param {String} tmxFile tmxFile fileName or content string - * @param {String} resourcePath If tmxFile is a file name ,it is not required.If tmxFile is content string ,it is must required. - * @return {cc.TMXTiledMap|undefined} - */ -cc.TMXTiledMap.create = function (tmxFile,resourcePath) { - return new cc.TMXTiledMap(tmxFile,resourcePath); -}; diff --git a/cocos2d/tilemap/CCTMXXMLParser.js b/cocos2d/tilemap/CCTMXXMLParser.js index 5133b09cc5..af7a3bc3e6 100644 --- a/cocos2d/tilemap/CCTMXXMLParser.js +++ b/cocos2d/tilemap/CCTMXXMLParser.js @@ -289,6 +289,7 @@ cc.TMXMapInfo = cc.SAXParser.extend(/** @lends cc.TMXMapInfo# */{ this._objectGroups = []; this.properties = []; this._tileProperties = {}; + this._tileAnimations = {}; this._currentFirstGID = 0; @@ -638,6 +639,24 @@ cc.TMXMapInfo = cc.SAXParser.extend(/** @lends cc.TMXMapInfo# */{ } this._tileProperties[this.parentGID] = dict; } + + var animation = t.getElementsByTagName("animation"); + if(animation) animation = animation[0];//i think there can only be one animation defined for each tile + + if(animation) + { + this._tileAnimations[this.parentGID] = []; + var frames = animation.children; + for(var i=0;i 0) { - childNode.sortAllChildren(); - // draw children zOrder < 0 - for (i = 0; i < len; i++) { - child = children[i]; - if (child._localZOrder < 0) - child._renderCmd.visit(cmd); - else - break; - } - cc.renderer.pushRenderCommand(cmd); - for (; i < len; i++) - children[i]._renderCmd.visit(cmd); - } else { - cc.renderer.pushRenderCommand(cmd); - } - this._dirtyFlag = 0; - }; - - proto.visit = function(parentCmd){ - var node = this._node; - // quick return if not visible. children won't be drawn. - if (!node._visible) - return; - - this.updateStatus(parentCmd); - node.sortAllChildren(); - - cc.renderer.pushRenderCommand(this._startRenderCmd); - this.rendering(); - cc.renderer.pushRenderCommand(this._RestoreRenderCmd); - - this._cacheDirty = false; - }; })(); \ No newline at end of file diff --git a/extensions/cocostudio/armature/CCBone.js b/extensions/cocostudio/armature/CCBone.js index 8f116fa6e8..8923ba6bf5 100644 --- a/extensions/cocostudio/armature/CCBone.js +++ b/extensions/cocostudio/armature/CCBone.js @@ -630,9 +630,6 @@ ccs.Bone = ccs.Node.extend(/** @lends ccs.Bone# */{ }, _createRenderCmd: function(){ - if(cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new ccs.Bone.CanvasRenderCmd(this); - else return new ccs.Bone.WebGLRenderCmd(this); } }); @@ -688,16 +685,6 @@ ccs.Bone.RenderCmd = { } }; -(function(){ - ccs.Bone.CanvasRenderCmd = function(renderable){ - cc.Node.CanvasRenderCmd.call(this, renderable); - this._needDraw = false; - }; - - var proto = ccs.Bone.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype); - cc.inject(ccs.Bone.RenderCmd, proto); - proto.constructor = ccs.Bone.CanvasRenderCmd; -})(); (function(){ if(!cc.Node.WebGLRenderCmd) diff --git a/extensions/cocostudio/armature/display/CCSkin.js b/extensions/cocostudio/armature/display/CCSkin.js index 4553cf568b..617fd4f546 100644 --- a/extensions/cocostudio/armature/display/CCSkin.js +++ b/extensions/cocostudio/armature/display/CCSkin.js @@ -174,9 +174,6 @@ ccs.Skin = ccs.Sprite.extend(/** @lends ccs.Skin# */{ }, _createRenderCmd: function(){ - if(cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new ccs.Skin.CanvasRenderCmd(this); - else return new ccs.Skin.WebGLRenderCmd(this); } }); diff --git a/extensions/cocostudio/armature/display/CCSkinCanvasRenderCmd.js b/extensions/cocostudio/armature/display/CCSkinCanvasRenderCmd.js index 83504f8b14..e69de29bb2 100644 --- a/extensions/cocostudio/armature/display/CCSkinCanvasRenderCmd.js +++ b/extensions/cocostudio/armature/display/CCSkinCanvasRenderCmd.js @@ -1,58 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -(function(){ - ccs.Skin.RenderCmd = { - updateArmatureTransform: function () { - var node = this._node; - this._transform = cc.affineTransformConcat( - node._skinTransform, - node.bone.getNodeToArmatureTransform() - ); - this._dirtyFlag = this._dirtyFlag & cc.Node._dirtyFlags.transformDirty ^ this._dirtyFlag; - }, - - getNodeToWorldTransform: function () { - return cc.affineTransformConcat(this._transform, this._node.bone.getArmature().getNodeToWorldTransform()); - }, - - getNodeToWorldTransformAR: function () { - var displayTransform = this._transform, node = this._node; - this._anchorPointInPoints = cc.pointApplyAffineTransform(this._anchorPointInPoints, displayTransform); - displayTransform.tx = this._anchorPointInPoints.x; - displayTransform.ty = this._anchorPointInPoints.y; - return cc.affineTransformConcat(displayTransform, node.bone.getArmature().getNodeToWorldTransform()); - } - }; - - ccs.Skin.CanvasRenderCmd = function(renderable){ - cc.Sprite.CanvasRenderCmd.call(this, renderable); - this._needDraw = true; - }; - - var proto = ccs.Skin.CanvasRenderCmd.prototype = Object.create(cc.Sprite.CanvasRenderCmd.prototype); - cc.inject(ccs.Skin.RenderCmd, proto); - proto.constructor = ccs.Skin.CanvasRenderCmd; -})(); diff --git a/extensions/cocostudio/timeline/CCBoneNode.js b/extensions/cocostudio/timeline/CCBoneNode.js index 2f6a95e1b0..9d7d5d2a68 100644 --- a/extensions/cocostudio/timeline/CCBoneNode.js +++ b/extensions/cocostudio/timeline/CCBoneNode.js @@ -504,9 +504,6 @@ ccs.BoneNode = (function () { }, _createRenderCmd: function () { - if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new BoneNodeCanvasCmd(this); - else return new BoneNodeWebGLCmd(this); } }); @@ -518,39 +515,6 @@ ccs.BoneNode = (function () { return new ccui.BoneNode(length, color); }; - var BoneNodeCanvasCmd = (function () { - - var BoneNodeCanvasCmd = function (node) { - Node.CanvasRenderCmd.call(this, node); - this._debug = false; - this._color = cc.color.WHITE; - this._drawNode = new cc.DrawNode(); - }; - - var proto = BoneNodeCanvasCmd.prototype = Object.create(Node.CanvasRenderCmd.prototype); - proto.constructor = BoneNodeCanvasCmd; - - proto.visit = function (parentCmd) { - var node = this._node; - node._visit && node._visit(parentCmd); - }; - proto.updateDebugPoint = function (points) { - this._drawNode.clear(); - this._drawNode.drawPoly(points, this._color, 0, this._color); - }; - - proto.transform = function (parentCmd, recursive) { - var rootSkeleton = this._node._rootSkeleton; - Node.CanvasRenderCmd.prototype.transform.call(this, parentCmd, recursive); - if (rootSkeleton && rootSkeleton._renderCmd._debug) { - this._drawNode._renderCmd.transform(this); - } - }; - - return BoneNodeCanvasCmd; - - })(); - var BoneNodeWebGLCmd = (function () { var BoneNodeWebGLCmd = function (node) { diff --git a/extensions/gui/scrollview/CCScrollView.js b/extensions/gui/scrollview/CCScrollView.js index 3aaeeb4ac0..ae7d178492 100644 --- a/extensions/gui/scrollview/CCScrollView.js +++ b/extensions/gui/scrollview/CCScrollView.js @@ -776,11 +776,8 @@ cc.ScrollView = cc.Layer.extend(/** @lends cc.ScrollView# */{ }, _createRenderCmd: function(){ - if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) { - return new cc.ScrollView.CanvasRenderCmd(this); - } else { - return new cc.ScrollView.WebGLRenderCmd(this); - } + return new cc.ScrollView.WebGLRenderCmd(this); + } }); diff --git a/extensions/gui/scrollview/CCScrollViewCanvasRenderCmd.js b/extensions/gui/scrollview/CCScrollViewCanvasRenderCmd.js index 3fdc92851f..8b13789179 100644 --- a/extensions/gui/scrollview/CCScrollViewCanvasRenderCmd.js +++ b/extensions/gui/scrollview/CCScrollViewCanvasRenderCmd.js @@ -1,81 +1 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -(function() { - cc.ScrollView.CanvasRenderCmd = function(renderable){ - cc.Layer.CanvasRenderCmd.call(this, renderable); - this._needDraw = false; - - this.startCmd = new cc.CustomRenderCmd(this, this._startCmd); - this.endCmd = new cc.CustomRenderCmd(this, this._endCmd); - }; - - var proto = cc.ScrollView.CanvasRenderCmd.prototype = Object.create(cc.Layer.CanvasRenderCmd.prototype); - proto.constructor = cc.ScrollView.CanvasRenderCmd; - - proto._startCmd = function(ctx, scaleX, scaleY){ - var node = this._node; - var wrapper = ctx || cc._renderContext, context = wrapper.getContext(); - wrapper.save(); - - if (node._clippingToBounds) { - this._scissorRestored = false; - wrapper.setTransform(this._worldTransform, scaleX, scaleY); - - var locScaleX = node.getScaleX(), locScaleY = node.getScaleY(); - - var getWidth = (node._viewSize.width * locScaleX) * scaleX; - var getHeight = (node._viewSize.height * locScaleY) * scaleY; - - context.beginPath(); - context.rect(0, 0, getWidth, -getHeight); - context.closePath(); - context.clip(); - } - }; - - proto._endCmd = function(wrapper){ - wrapper = wrapper || cc._renderContext; - wrapper.restore(); - }; - - proto.visit = function(parentCmd){ - var node = this._node; - if (!node._visible) return; - - var i, locChildren = node._children, childrenLen; - - this.transform(parentCmd); - cc.renderer.pushRenderCommand(this.startCmd); - - if (locChildren && locChildren.length > 0) { - childrenLen = locChildren.length; - node.sortAllChildren(); - for (i = 0; i < childrenLen; i++) { - locChildren[i]._renderCmd.visit(this); - } - } - cc.renderer.pushRenderCommand(this.endCmd); - }; -})(); diff --git a/extensions/spine/CCSkeleton.js b/extensions/spine/CCSkeleton.js index 9bab9e8d16..e69de29bb2 100644 --- a/extensions/spine/CCSkeleton.js +++ b/extensions/spine/CCSkeleton.js @@ -1,405 +0,0 @@ -/**************************************************************************** - Copyright (c) 2011-2012 cocos2d-x.org - Copyright (c) 2013-2014 Chukong Technologies Inc. - Copyright (c) 2014 Shengxiang Chen (Nero Chan) - - 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. - ****************************************************************************/ - -/** - * The main namespace of Spine, all classes, functions, properties and constants of Spine are defined in this namespace - * @namespace - * @name sp - */ -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 -}; - -/** - *

- * The skeleton of Spine.
- * Skeleton has a reference to a SkeletonData and stores the state for skeleton instance, - * which consists of the current pose's bone SRT, slot colors, and which slot attachments are visible.
- * Multiple skeletons can use the same SkeletonData (which includes all animations, skins, and attachments).
- *

- * @class - * @extends cc.Node - */ -sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{ - _skeleton: null, - _rootBone: null, - _timeScale: 1, - _debugSlots: false, - _debugBones: false, - _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. - */ - ctor:function(skeletonDataFile, atlasFile, scale){ - cc.Node.prototype.ctor.call(this); - - if(arguments.length === 0) - this.init(); - else - this.initWithArgs(skeletonDataFile, atlasFile, scale); - }, - - _createRenderCmd:function () { - if(cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new sp.Skeleton.CanvasRenderCmd(this); - else - return new sp.Skeleton.WebGLRenderCmd(this); - }, - - /** - * Initializes a sp.Skeleton. please do not call this function by yourself, you should pass the parameters to constructor to initialize it. - */ - 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}; - this.scheduleUpdate(); - }, - - /** - * Sets whether open debug slots. - * @param {boolean} enable true to open, false to close. - */ - setDebugSolots:function(enable){ - this._debugSlots = enable; - }, - - /** - * Sets whether open debug bones. - * @param {boolean} enable - */ - setDebugBones:function(enable){ - this._debugBones = enable; - }, - - /** - * Sets whether open debug slots. - * @param {boolean} enabled true to open, false to close. - */ - setDebugSlotsEnabled: function(enabled) { - this._debugSlots = enabled; - }, - - /** - * Gets whether open debug slots. - * @returns {boolean} true to open, false to close. - */ - getDebugSlotsEnabled: function() { - return this._debugSlots; - }, - - /** - * Sets whether open debug bones. - * @param {boolean} enabled - */ - setDebugBonesEnabled: function(enabled) { - this._debugBones = enabled; - }, - - /** - * Gets whether open debug bones. - * @returns {boolean} true to open, false to close. - */ - getDebugBonesEnabled: function() { - return this._debugBones; - }, - - /** - * Sets the time scale of sp.Skeleton. - * @param {Number} scale - */ - setTimeScale:function(scale){ - this._timeScale = scale; - }, - - getTimeScale: function(){ - return this._timeScale; - }, - - /** - * Initializes sp.Skeleton with Data. - * @param {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. - */ - initWithArgs: function (skeletonDataFile, atlasFile, scale) { - var argSkeletonFile = skeletonDataFile, argAtlasFile = atlasFile, - skeletonData, atlas, ownsSkeletonData; - - if (cc.isString(argSkeletonFile)) { - if (cc.isString(argAtlasFile)) { - var data = cc.loader.getRes(argAtlasFile); - sp._atlasLoader.setAtlasFile(argAtlasFile); - atlas = new spine.Atlas(data, sp._atlasLoader); - } else { - atlas = atlasFile; - } - scale = scale || 1 / cc.director.getContentScaleFactor(); - - var attachmentLoader = new spine.AtlasAttachmentLoader(atlas); - var skeletonJsonReader = new spine.SkeletonJson(attachmentLoader); - skeletonJsonReader.scale = scale; - - var skeletonJson = cc.loader.getRes(argSkeletonFile); - skeletonData = skeletonJsonReader.readSkeletonData(skeletonJson); - atlas.dispose(skeletonJsonReader); - ownsSkeletonData = true; - } else { - skeletonData = skeletonDataFile; - ownsSkeletonData = atlasFile; - } - this.setSkeletonData(skeletonData, ownsSkeletonData); - this.init(); - }, - - /** - * Returns the bounding box of sp.Skeleton. - * @returns {cc.Rect} - */ - 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 = [], - slots = this._skeleton.slots, VERTEX = sp.VERTEX_INDEX; - - for (var i = 0, slotCount = slots.length; i < slotCount; ++i) { - var slot = slots[i]; - if (!slot.attachment || slot.attachment.type != sp.ATTACHMENT_TYPE.REGION) - continue; - var attachment = slot.attachment; - this._computeRegionAttachmentWorldVertices(attachment, slot.bone.skeleton.x, slot.bone.skeleton.y, slot.bone, vertices); - 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); - } - var position = this.getPosition(); - return cc.rect(position.x + minX, position.y + minY, maxX - minX, maxY - minY); - }, - - _computeRegionAttachmentWorldVertices : function(self, x, y, bone, vertices){ - var offset = self.offset, vertexIndex = sp.VERTEX_INDEX; - x += bone.worldX; - y += bone.worldY; - vertices[vertexIndex.X1] = offset[vertexIndex.X1] * bone.m00 + offset[vertexIndex.Y1] * bone.m01 + x; - vertices[vertexIndex.Y1] = offset[vertexIndex.X1] * bone.m10 + offset[vertexIndex.Y1] * bone.m11 + y; - vertices[vertexIndex.X2] = offset[vertexIndex.X2] * bone.m00 + offset[vertexIndex.Y2] * bone.m01 + x; - vertices[vertexIndex.Y2] = offset[vertexIndex.X2] * bone.m10 + offset[vertexIndex.Y2] * bone.m11 + y; - vertices[vertexIndex.X3] = offset[vertexIndex.X3] * bone.m00 + offset[vertexIndex.Y3] * bone.m01 + x; - vertices[vertexIndex.Y3] = offset[vertexIndex.X3] * bone.m10 + offset[vertexIndex.Y3] * bone.m11 + y; - vertices[vertexIndex.X4] = offset[vertexIndex.X4] * bone.m00 + offset[vertexIndex.Y4] * bone.m01 + x; - vertices[vertexIndex.Y4] = offset[vertexIndex.X4] * bone.m10 + offset[vertexIndex.Y4] * bone.m11 + y; - }, - - /** - * Computes the world SRT from the local SRT for each bone. - */ - updateWorldTransform: function () { - this._skeleton.updateWorldTransform(); - }, - - /** - * Sets the bones and slots to the setup pose. - */ - setToSetupPose: function () { - this._skeleton.setToSetupPose(); - }, - - /** - * Sets the bones to the setup pose, using the values from the `BoneData` list in the `SkeletonData`. - */ - setBonesToSetupPose: function () { - this._skeleton.setBonesToSetupPose(); - }, - - /** - * Sets the slots to the setup pose, using the values from the `SlotData` list in the `SkeletonData`. - */ - setSlotsToSetupPose: function () { - this._skeleton.setSlotsToSetupPose(); - }, - - /** - * Finds a bone by name. This does a string comparison for every bone. - * @param {String} boneName - * @returns {spine.Bone} - */ - findBone: function (boneName) { - return this._skeleton.findBone(boneName); - }, - - /** - * Finds a slot by name. This does a string comparison for every slot. - * @param {String} slotName - * @returns {spine.Slot} - */ - findSlot: function (slotName) { - return this._skeleton.findSlot(slotName); - }, - - /** - * 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} - */ - setSkin: function (skinName) { - return this._skeleton.setSkinByName(skinName); - }, - - /** - * 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} - */ - getAttachment: function (slotName, attachmentName) { - return this._skeleton.getAttachmentBySlotName(slotName, attachmentName); - }, - - /** - * Sets 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 - */ - setAttachment: function (slotName, attachmentName) { - this._skeleton.setAttachment(slotName, attachmentName); - }, - - /** - * Sets the premultiplied alpha value to sp.Skeleton. - * @param {Number} alpha - */ - setPremultipliedAlpha: function (premultiplied) { - this._premultipliedAlpha = premultiplied; - }, - - /** - * Returns whether to enable premultiplied alpha. - * @returns {boolean} - */ - isPremultipliedAlpha: function () { - return this._premultipliedAlpha; - }, - - /** - * Sets skeleton data to sp.Skeleton. - * @param {spine.SkeletonData} skeletonData - * @param {spine.SkeletonData} ownsSkeletonData - */ - setSkeletonData: function (skeletonData, ownsSkeletonData) { - if(skeletonData.width != null && skeletonData.height != null) - this.setContentSize(skeletonData.width / cc.director.getContentScaleFactor(), skeletonData.height / cc.director.getContentScaleFactor()); - - this._skeleton = new spine.Skeleton(skeletonData); - this._skeleton.updateWorldTransform(); - this._rootBone = this._skeleton.getRootBone(); - this._ownsSkeletonData = ownsSkeletonData; - - this._renderCmd._createChildFormSkeletonData(); - }, - - /** - * Return the renderer of attachment. - * @param {spine.RegionAttachment|spine.BoundingBoxAttachment} regionAttachment - * @returns {cc.Node} - */ - getTextureAtlas: function (regionAttachment) { - return regionAttachment.rendererObject.page.rendererObject; - }, - - /** - * Returns the blendFunc of sp.Skeleton. - * @returns {cc.BlendFunc} - */ - getBlendFunc: function () { - return this._blendFunc; - }, - - /** - * Sets the blendFunc of sp.Skeleton. - * @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; - } - }, - - /** - * Update will be called automatically every frame if "scheduleUpdate" is called when the node is "live". - * @param {Number} dt Delta time since last update - */ - update: function (dt) { - this._skeleton.update(dt); - } -}); - -/** - * Creates a skeleton object. - * @deprecated since v3.0, please use new sp.Skeleton(skeletonDataFile, atlasFile, scale) instead. - * @param {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. - * @returns {sp.Skeleton} - */ -sp.Skeleton.create = function (skeletonDataFile, atlasFile/* or atlas*/, scale) { - return new sp.Skeleton(skeletonDataFile, atlasFile, scale); -}; diff --git a/extensions/spine/CCSkeletonAnimation.js b/extensions/spine/CCSkeletonAnimation.js index f78d56cc89..e69de29bb2 100644 --- a/extensions/spine/CCSkeletonAnimation.js +++ b/extensions/spine/CCSkeletonAnimation.js @@ -1,348 +0,0 @@ -/**************************************************************************** - Copyright (c) 2011-2012 cocos2d-x.org - Copyright (c) 2013-2014 Chukong Technologies Inc. - Copyright (c) 2014 Shengxiang Chen (Nero Chan) - - 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. - ****************************************************************************/ - -/** - * @ignore - */ -sp._atlasPage_createTexture_webGL = function (self, path) { - var texture = cc.textureCache.addImage(path); - self.rendererObject = new cc.TextureAtlas(texture, 128); - self.width = texture.getPixelsWide(); - self.height = texture.getPixelsHigh(); -}; - -sp._atlasPage_createTexture_canvas = function(self, path) { - self._texture = cc.textureCache.addImage(path); -}; - -sp._atlasPage_disposeTexture = function (self) { - self.rendererObject.release(); -}; - -sp._atlasLoader = { - spAtlasFile:null, - setAtlasFile:function(spAtlasFile){ - this.spAtlasFile = spAtlasFile; - }, - load:function(page, line, spAtlas){ - var texturePath = cc.path.join(cc.path.dirname(this.spAtlasFile), line); - if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) - sp._atlasPage_createTexture_webGL(page,texturePath); - else - sp._atlasPage_createTexture_canvas(page,texturePath); - }, - unload:function(obj){ - } -}; - -/** - * The event type of spine skeleton animation. It contains event types: START(0), END(1), COMPLETE(2), EVENT(3). - * @constant - * @type {{START: number, END: number, COMPLETE: number, EVENT: number}} - */ -sp.ANIMATION_EVENT_TYPE = { - START: 0, - END: 1, - COMPLETE: 2, - EVENT: 3 -}; - -sp.TrackEntryListeners = function(startListener, endListener, completeListener, eventListener){ - this.startListener = startListener || null; - this.endListener = endListener || null; - this.completeListener = completeListener || null; - this.eventListener = eventListener || null; -}; - -sp.TrackEntryListeners.getListeners = function(entry){ - if(!entry.rendererObject){ - entry.rendererObject = new sp.TrackEntryListeners(); - entry.listener = sp.trackEntryCallback; - } - return entry.rendererObject; -}; - -sp.trackEntryCallback = function(state, trackIndex, type, event, loopCount) { - state.rendererObject.onTrackEntryEvent(trackIndex, type, event, loopCount); -}; - -/** - * The skeleton animation of spine. It updates animation's state and skeleton's world transform. - * @class - * @extends sp.Skeleton - * @example - * var spineBoy = new sp.SkeletonAnimation('res/skeletons/spineboy.json', 'res/skeletons/spineboy.atlas'); - * this.addChild(spineBoy, 4); - */ -sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{ - _state: null, - _target: null, - _callback: null, - - _ownsAnimationStateData: false, - _startListener: null, - _endListener: null, - _completeListener: null, - _eventListener: null, - - /** - * Initializes a sp.SkeletonAnimation. please do not call this function by yourself, you should pass the parameters to constructor to initialize it. - * @override - */ - init: function () { - sp.Skeleton.prototype.init.call(this); - this._ownsAnimationStateData = true; - this.setAnimationStateData(new spine.AnimationStateData(this._skeleton.data)); - }, - - /** - * Sets animation state data to sp.SkeletonAnimation. - * @param {spine.AnimationStateData} stateData - */ - setAnimationStateData: function (stateData) { - var state = new spine.AnimationState(stateData); - state.rendererObject = this; - state.onStart = this._onAnimationStateStart.bind(this); - state.onComplete = this._onAnimationStateComplete.bind(this); - state.onEnd = this._onAnimationStateEnd.bind(this); - state.onEvent = this._onAnimationStateEvent.bind(this); - this._state = state; - }, - - /** - * Mix applies all keyframe values, interpolated for the specified time and mixed with the current values.
- * @param {String} fromAnimation - * @param {String} toAnimation - * @param {Number} duration - */ - setMix: function (fromAnimation, toAnimation, duration) { - this._state.data.setMixByName(fromAnimation, toAnimation, duration); - }, - - /** - * Sets event listener of sp.SkeletonAnimation. - * @param {Object} target - * @param {Function} callback - */ - setAnimationListener: function (target, callback) { - this._target = target; - this._callback = callback; - }, - - /** - * Set the current animation. Any queued animations are cleared. - * @param {Number} trackIndex - * @param {String} name - * @param {Boolean} loop - * @returns {spine.TrackEntry|null} - */ - setAnimation: function (trackIndex, name, loop) { - var animation = this._skeleton.data.findAnimation(name); - if (!animation) { - cc.log("Spine: Animation not found: " + name); - return null; - } - return this._state.setAnimation(trackIndex, animation, loop); - }, - - /** - * Adds an animation to be played delay seconds after the current or last queued animation. - * @param {Number} trackIndex - * @param {String} name - * @param {Boolean} loop - * @param {Number} [delay=0] - * @returns {spine.TrackEntry|null} - */ - addAnimation: function (trackIndex, name, loop, delay) { - delay = delay == null ? 0 : delay; - var animation = this._skeleton.data.findAnimation(name); - if (!animation) { - cc.log("Spine: Animation not found:" + name); - return null; - } - return this._state.addAnimation(trackIndex, animation, loop, delay); - }, - - /** - * Returns track entry by trackIndex. - * @param trackIndex - * @returns {spine.TrackEntry|null} - */ - getCurrent: function (trackIndex) { - return this._state.getCurrent(trackIndex); - }, - - /** - * Clears all tracks of animation state. - */ - clearTracks: function () { - this._state.clearTracks(); - }, - - /** - * Clears track of animation state by trackIndex. - * @param {Number} trackIndex - */ - clearTrack: function (trackIndex) { - this._state.clearTrack(trackIndex); - }, - - /** - * Update will be called automatically every frame if "scheduleUpdate" is called when the node is "live". - * It updates animation's state and skeleton's world transform. - * @param {Number} dt Delta time since last update - * @override - */ - update: function (dt) { - this._super(dt); - dt *= this._timeScale; - this._state.update(dt); - this._state.apply(this._skeleton); - this._skeleton.updateWorldTransform(); - this._renderCmd._updateChild(); - }, - - /** - * Set the start event listener. - * @param {function} listener - */ - setStartListener: function(listener){ - this._startListener = listener; - }, - - /** - * Set the end event listener. - * @param {function} listener - */ - setEndListener: function(listener) { - this._endListener = listener; - }, - - setCompleteListener: function(listener) { - this._completeListener = listener; - }, - - setEventListener: function(listener){ - this._eventListener = listener; - }, - - setTrackStartListener: function(entry, listener){ - sp.TrackEntryListeners.getListeners(entry).startListener = listener; - }, - - setTrackEndListener: function(entry, listener){ - sp.TrackEntryListeners.getListeners(entry).endListener = listener; - }, - - setTrackCompleteListener: function(entry, listener){ - sp.TrackEntryListeners.getListeners(entry).completeListener = listener; - }, - - setTrackEventListener: function(entry, listener){ - sp.TrackEntryListeners.getListeners(entry).eventListener = listener; - }, - - onTrackEntryEvent: function(traceIndex, type, event, loopCount){ - var entry = this._state.getCurrent(traceIndex); - if(!entry.rendererObject) - return; - var listeners = entry.rendererObject; - switch (type){ - case sp.ANIMATION_EVENT_TYPE.START: - if(listeners.startListener) - listeners.startListener(traceIndex); - break; - case sp.ANIMATION_EVENT_TYPE.END: - if(listeners.endListener) - listeners.endListener(traceIndex); - break; - case sp.ANIMATION_EVENT_TYPE.COMPLETE: - if(listeners.completeListener) - listeners.completeListener(traceIndex, loopCount); - break; - case sp.ANIMATION_EVENT_TYPE.EVENT: - if(listeners.eventListener) - listeners.eventListener(traceIndex, event); - break; - } - }, - - onAnimationStateEvent: function(trackIndex, type, event, loopCount) { - switch(type){ - case sp.ANIMATION_EVENT_TYPE.START: - if(this._startListener) - this._startListener(trackIndex); - break; - case sp.ANIMATION_EVENT_TYPE.END: - if(this._endListener) - this._endListener(trackIndex); - break; - case sp.ANIMATION_EVENT_TYPE.COMPLETE: - if(this._completeListener) - this._completeListener(trackIndex, loopCount); - break; - case sp.ANIMATION_EVENT_TYPE.EVENT: - if(this._eventListener) - this._eventListener(trackIndex, event); - break; - } - }, - - getState: function(){ - return this._state; - }, - - _onAnimationStateStart: function (trackIndex) { - this._animationStateCallback(trackIndex, sp.ANIMATION_EVENT_TYPE.START, null, 0); - }, - _onAnimationStateEnd: function (trackIndex) { - this._animationStateCallback(trackIndex, sp.ANIMATION_EVENT_TYPE.END, null, 0); - }, - _onAnimationStateComplete: function (trackIndex, count) { - this._animationStateCallback(trackIndex, sp.ANIMATION_EVENT_TYPE.COMPLETE, null, count); - }, - _onAnimationStateEvent: function (trackIndex, event) { - this._animationStateCallback(trackIndex, sp.ANIMATION_EVENT_TYPE.EVENT, event, 0); - }, - _animationStateCallback: function (trackIndex, type, event, loopCount) { - this.onAnimationStateEvent(trackIndex, type, event, loopCount); - if (this._target && this._callback) { - this._callback.call(this._target, this, trackIndex, type, event, loopCount) - } - } -}); - -/** - * Creates a skeleton animation object. - * @deprecated since v3.0, please use new sp.SkeletonAnimation(skeletonDataFile, atlasFile, scale) instead. - * @param {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. - * @returns {sp.Skeleton} - */ -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 1b4f873cd1..e69de29bb2 100644 --- a/extensions/spine/CCSkeletonCanvasRenderCmd.js +++ b/extensions/spine/CCSkeletonCanvasRenderCmd.js @@ -1,213 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -(function(){ - sp.Skeleton.CanvasRenderCmd = function(renderableObject){ - cc.Node.CanvasRenderCmd.call(this, 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.type != sp.ATTACHMENT_TYPE.REGION) - continue; - attachment = slot.attachment; - this._updateRegionAttachmentSlot(attachment, slot, 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.m00 + bone.worldX; - var y = bone.data.length * bone.m10 + bone.worldY; - drawingUtil.drawLine( - {x: bone.worldX, y: bone.worldY}, - {x: x, y: y}); - } - - // 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({x: bone.worldX, y: bone.worldY}); - if (i === 0) - drawingUtil.setDrawColor(0, 255, 0, 255); - } - } - }; - - proto._updateRegionAttachmentSlot = function(attachment, slot, points) { - if(!points) - return; - - var vertices = {}, VERTEX = sp.VERTEX_INDEX, bone = slot.bone; - attachment.computeVertices(bone.skeleton.x, bone.skeleton.y, bone, vertices); - 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.rendererObject.name; - sprite = this._createSprite(slot, attachment); - slot.currentSprite = sprite; - slot.currentSpriteName = spriteName; - slotNode.addChild(sprite); - } else if(attachment instanceof spine.MeshAttachment){ - //todo for mesh - } - } - }; - - proto._createSprite = function(slot, attachment){ - var rendererObject = attachment.rendererObject; - var texture = rendererObject.page._texture; - var rect = new cc.Rect(rendererObject.x, rendererObject.y, rendererObject.width, rendererObject.height); - var sprite = new cc.Sprite(); - sprite.initWithTexture(rendererObject.page._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); - - slot.sprites = slot.sprites || {}; - slot.sprites[rendererObject.name] = sprite; - - return sprite; - }; - - proto._updateChild = function(){ - var locSkeleton = this._node._skeleton, slots = locSkeleton.slots; - var i, n, selSprite; - - 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; - } - var type = attachment.type; - if (type === spine.AttachmentType.region){ - if(attachment.rendererObject){ - if(!slot.currentSpriteName || slot.currentSpriteName !== attachment.name){ - var spriteName = attachment.rendererObject.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; - slotNode.setPosition(bone.worldX + attachment.x * bone.m00 + attachment.y * bone.m01, - bone.worldY + attachment.x * bone.m10 + attachment.y * bone.m11); - slotNode.setScale(bone.worldScaleX, bone.worldScaleY); - - //set the color and opacity - selSprite = slot.currentSprite; - selSprite._flippedX = bone.worldFlipX; - selSprite._flippedY = bone.worldFlipY; - if(selSprite._flippedY || selSprite._flippedX){ - slotNode.setRotation(bone.worldRotation); - selSprite.setRotation(attachment.rotation); - }else{ - slotNode.setRotation(-bone.worldRotation); - selSprite.setRotation(-attachment.rotation); - } - - //hack for sprite - selSprite._renderCmd._displayedOpacity = 0 | (locSkeleton.a * slot.a * 255); - var r = 0 | (locSkeleton.r * slot.r * 255), g = 0 | (locSkeleton.g * slot.g * 255), b = 0 | (locSkeleton.b * slot.b * 255); - selSprite.setColor(cc.color(r,g,b)); - selSprite._renderCmd._updateColor(); - } else if (type === spine.AttachmentType.skinnedmesh) { - //todo for mesh - } else { - slotNode.setVisible(false); - continue; - } - slotNode.setVisible(true); - } - }; -})(); \ No newline at end of file diff --git a/extensions/spine/CCSkeletonWebGLRenderCmd.js b/extensions/spine/CCSkeletonWebGLRenderCmd.js index 51d2184caa..e69de29bb2 100644 --- a/extensions/spine/CCSkeletonWebGLRenderCmd.js +++ b/extensions/spine/CCSkeletonWebGLRenderCmd.js @@ -1,260 +0,0 @@ -/**************************************************************************** - 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. - ****************************************************************************/ - -(function(){ - sp.Skeleton.WebGLRenderCmd = function (renderableObject) { - cc.Node.WebGLRenderCmd.call(this, renderableObject); - this._needDraw = true; - this.setShaderProgram(cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLOR)); - this._tmpQuad = new cc.V3F_C4B_T2F_Quad(); - }; - - var proto = sp.Skeleton.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype); - proto.constructor = sp.Skeleton.WebGLRenderCmd; - - proto.rendering = function (ctx) { - var node = this._node, tmpQuad = this._tmpQuad; - var color = node.getColor(), locSkeleton = node._skeleton; - - var blendMode, textureAtlas, attachment, slot, i, n; - var locBlendFunc = node._blendFunc; - var premultiAlpha = node._premultipliedAlpha; - - this._shaderProgram.use(); - this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix); - // cc.glBlendFunc(locBlendFunc.src, locBlendFunc.dst); - 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; - } - - //for (i = 0, n = locSkeleton.slots.length; i < n; i++) { - for (i = 0, n = locSkeleton.drawOrder.length; i < n; i++) { - slot = locSkeleton.drawOrder[i]; - if (!slot.attachment) - continue; - attachment = slot.attachment; - - switch(slot.attachment.type) { - case sp.ATTACHMENT_TYPE.REGION: - this._updateRegionAttachmentQuad(attachment, slot, tmpQuad, premultiAlpha); - break; - case sp.ATTACHMENT_TYPE.MESH: - this._updateMeshAttachmentQuad(attachment, slot, tmpQuad, premultiAlpha); - break; - case sp.ATTACHMENT_TYPE.SKINNED_MESH: - break; - default: - continue; - } - - var regionTextureAtlas = node.getTextureAtlas(attachment); - - if (slot.data.blendMode != blendMode) { - if (textureAtlas) { - textureAtlas.drawQuads(); - textureAtlas.removeAllQuads(); - } - blendMode = slot.data.blendMode; - switch (blendMode) { - case spine.BlendMode.additive: - cc.glBlendFunc(premultiAlpha ? cc.ONE : cc.SRC_ALPHA, cc.ONE); - break; - case spine.BlendMode.multiply: - cc.glBlendFunc(cc.DST_COLOR, cc.ONE_MINUS_SRC_ALPHA); - break; - case spine.BlendMode.screen: - cc.glBlendFunc(cc.ONE, cc.ONE_MINUS_SRC_COLOR); - break; - default: - cc.glBlendFunc(locBlendFunc.src, locBlendFunc.dst); - } - } else if (regionTextureAtlas != textureAtlas && textureAtlas) { - textureAtlas.drawQuads(); - textureAtlas.removeAllQuads(); - } - textureAtlas = regionTextureAtlas; - - var quadCount = textureAtlas.getTotalQuads(); - if (textureAtlas.getCapacity() == quadCount) { - textureAtlas.drawQuads(); - textureAtlas.removeAllQuads(); - if (!textureAtlas.resizeCapacity(textureAtlas.getCapacity() * 2)) - return; - } - - textureAtlas.updateQuad(tmpQuad, quadCount); - } - - if (textureAtlas) { - textureAtlas.drawQuads(); - textureAtlas.removeAllQuads(); - } - - if (node._debugBones || node._debugSlots) { - cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW); - //cc.kmGLPushMatrixWitMat4(this._stackMatrix); - cc.current_stack.stack.push(cc.current_stack.top); - cc.current_stack.top = this._stackMatrix; - var drawingUtil = cc._drawingUtil; - - if (node._debugSlots) { - // Slots. - drawingUtil.setDrawColor(0, 0, 255, 255); - drawingUtil.setLineWidth(1); - - for (i = 0, n = locSkeleton.slots.length; i < n; i++) { - slot = locSkeleton.drawOrder[i]; - if (!slot.attachment || slot.attachment.type != sp.ATTACHMENT_TYPE.REGION) - continue; - attachment = slot.attachment; - this._updateRegionAttachmentQuad(attachment, slot, tmpQuad); - - var points = []; - points.push(cc.p(tmpQuad.bl.vertices.x, tmpQuad.bl.vertices.y)); - points.push(cc.p(tmpQuad.br.vertices.x, tmpQuad.br.vertices.y)); - points.push(cc.p(tmpQuad.tr.vertices.x, tmpQuad.tr.vertices.y)); - points.push(cc.p(tmpQuad.tl.vertices.x, tmpQuad.tl.vertices.y)); - - 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.m00 + bone.worldX; - var y = bone.data.length * bone.m10 + 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. - - 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(); - } - }; - - proto._createChildFormSkeletonData = function(){}; - - proto._updateChild = function(){}; - - proto._updateRegionAttachmentQuad = function(self, slot, quad, premultipliedAlpha) { - var vertices = {}; - self.computeVertices(slot.bone.skeleton.x, slot.bone.skeleton.y, slot.bone, vertices); - var r = slot.bone.skeleton.r * slot.r * 255; - var g = slot.bone.skeleton.g * slot.g * 255; - var b = slot.bone.skeleton.b * slot.b * 255; - var normalizedAlpha = slot.bone.skeleton.a * slot.a; - - if (premultipliedAlpha) { - r *= normalizedAlpha; - g *= normalizedAlpha; - b *= normalizedAlpha; - } - var a = normalizedAlpha * 255; - - quad.bl.colors.r = quad.tl.colors.r = quad.tr.colors.r = quad.br.colors.r = r; - quad.bl.colors.g = quad.tl.colors.g = quad.tr.colors.g = quad.br.colors.g = g; - quad.bl.colors.b = quad.tl.colors.b = quad.tr.colors.b = quad.br.colors.b = b; - quad.bl.colors.a = quad.tl.colors.a = quad.tr.colors.a = quad.br.colors.a = a; - - var VERTEX = sp.VERTEX_INDEX; - quad.bl.vertices.x = vertices[VERTEX.X1]; - quad.bl.vertices.y = vertices[VERTEX.Y1]; - quad.tl.vertices.x = vertices[VERTEX.X2]; - quad.tl.vertices.y = vertices[VERTEX.Y2]; - quad.tr.vertices.x = vertices[VERTEX.X3]; - quad.tr.vertices.y = vertices[VERTEX.Y3]; - quad.br.vertices.x = vertices[VERTEX.X4]; - quad.br.vertices.y = vertices[VERTEX.Y4]; - - quad.bl.texCoords.u = self.uvs[VERTEX.X1]; - quad.bl.texCoords.v = self.uvs[VERTEX.Y1]; - quad.tl.texCoords.u = self.uvs[VERTEX.X2]; - quad.tl.texCoords.v = self.uvs[VERTEX.Y2]; - quad.tr.texCoords.u = self.uvs[VERTEX.X3]; - quad.tr.texCoords.v = self.uvs[VERTEX.Y3]; - quad.br.texCoords.u = self.uvs[VERTEX.X4]; - quad.br.texCoords.v = self.uvs[VERTEX.Y4]; - }; - - proto._updateMeshAttachmentQuad = function(self, slot, quad, premultipliedAlpha) { - var vertices = {}; - self.computeWorldVertices(slot.bone.x, slot.bone.y, slot, vertices); - var r = slot.bone.skeleton.r * slot.r * 255; - var g = slot.bone.skeleton.g * slot.g * 255; - var b = slot.bone.skeleton.b * slot.b * 255; - var normalizedAlpha = slot.bone.skeleton.a * slot.a; - if (premultipliedAlpha) { - r *= normalizedAlpha; - g *= normalizedAlpha; - b *= normalizedAlpha; - } - var a = normalizedAlpha * 255; - - quad.bl.colors.r = quad.tl.colors.r = quad.tr.colors.r = quad.br.colors.r = r; - quad.bl.colors.g = quad.tl.colors.g = quad.tr.colors.g = quad.br.colors.g = g; - quad.bl.colors.b = quad.tl.colors.b = quad.tr.colors.b = quad.br.colors.b = b; - quad.bl.colors.a = quad.tl.colors.a = quad.tr.colors.a = quad.br.colors.a = a; - - var VERTEX = sp.VERTEX_INDEX; - quad.bl.vertices.x = vertices[VERTEX.X1]; - quad.bl.vertices.y = vertices[VERTEX.Y1]; - quad.tl.vertices.x = vertices[VERTEX.X2]; - quad.tl.vertices.y = vertices[VERTEX.Y2]; - quad.tr.vertices.x = vertices[VERTEX.X3]; - quad.tr.vertices.y = vertices[VERTEX.Y3]; - quad.br.vertices.x = vertices[VERTEX.X4]; - quad.br.vertices.y = vertices[VERTEX.Y4]; - - quad.bl.texCoords.u = self.uvs[VERTEX.X1]; - quad.bl.texCoords.v = self.uvs[VERTEX.Y1]; - quad.tl.texCoords.u = self.uvs[VERTEX.X2]; - quad.tl.texCoords.v = self.uvs[VERTEX.Y2]; - quad.tr.texCoords.u = self.uvs[VERTEX.X3]; - quad.tr.texCoords.v = self.uvs[VERTEX.Y3]; - quad.br.texCoords.u = self.uvs[VERTEX.X4]; - quad.br.texCoords.v = self.uvs[VERTEX.Y4]; - }; -})(); diff --git a/extensions/spine/Spine.js b/extensions/spine/Spine.js index d9bd118f59..e69de29bb2 100644 --- a/extensions/spine/Spine.js +++ b/extensions/spine/Spine.js @@ -1,2731 +0,0 @@ -/****************************************************************************** - * Spine Runtimes Software License - * Version 2.3 - * - * Copyright (c) 2013-2015, 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 (the "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 otherwise create derivative works, improvements of the - * Software or develop new applications using the Software 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; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) 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. - *****************************************************************************/ - -var spine = { - radDeg: 180 / Math.PI, - degRad: Math.PI / 180, - temp: [], - Float32Array: (typeof(Float32Array) === 'undefined') ? Array : Float32Array, - Uint16Array: (typeof(Uint16Array) === 'undefined') ? Array : Uint16Array -}; - -spine.BoneData = function (name, parent) { - this.length = this.x = this.y = this.rotation = 0; - this.scaleX = this.scaleY = 1; - - this.name = name; - this.parent = parent; -}; - -spine.BoneData.prototype = { - length: 0, - x: 0, y: 0, - rotation: 0, - scaleX: 1, scaleY: 1, - inheritScale: true, - inheritRotation: true, - flipX: false, flipY: false -}; - -spine.BlendMode = { - normal: 0, - additive: 1, - multiply: 2, - screen: 3 -}; - -spine.SlotData = function (name, boneData) { - this.r = this.g = this.b = this.a = 1; - this.blendMode = spine.BlendMode.normal; - - this.name = name; - this.boneData = boneData; -}; -spine.SlotData.prototype = { - r: 1, g: 1, b: 1, a: 1, - attachmentName: null, - blendMode: spine.BlendMode.normal -}; - -spine.IkConstraintData = function (name) { - this.bendDirection = this.mix = 1; - - this.name = name; - this.bones = []; -}; -spine.IkConstraintData.prototype = { - target: null, - bendDirection: 1, - mix: 1 -}; - -spine.Bone = function (boneData, skeleton, parent) { - this.x = this.y = this.rotation = this.rotationIK = 0; - this.scaleX = this.scaleY = 1; - this.flipX = this.flipY = false; - this.m00 = this.m01 = this.worldX = 0; // a b x - this.m10 = this.m11= this.worldY = 0; // c d y - this.worldRotation = 0; - this.worldScaleX = this.worldScaleY = 1; - this.worldFlipX = this.worldFlipY = false; - - this.data = boneData; - this.skeleton = skeleton; - this.parent = parent; - this.setToSetupPose(); -}; -spine.Bone.yDown = false; -spine.Bone.prototype = { - x: 0, y: 0, - rotation: 0, rotationIK: 0, - scaleX: 1, scaleY: 1, - flipX: false, flipY: false, - m00: 0, m01: 0, worldX: 0, // a b x - m10: 0, m11: 0, worldY: 0, // c d y - worldRotation: 0, - worldScaleX: 1, worldScaleY: 1, - worldFlipX: false, worldFlipY: false, - updateWorldTransform: function () { - var parent = this.parent; - if (parent) { - this.worldX = this.x * parent.m00 + this.y * parent.m01 + parent.worldX; - this.worldY = this.x * parent.m10 + this.y * parent.m11 + parent.worldY; - if (this.data.inheritScale) { - this.worldScaleX = parent.worldScaleX * this.scaleX; - this.worldScaleY = parent.worldScaleY * this.scaleY; - } else { - this.worldScaleX = this.scaleX; - this.worldScaleY = this.scaleY; - } - this.worldRotation = this.data.inheritRotation ? (parent.worldRotation + this.rotationIK) : this.rotationIK; - this.worldFlipX = parent.worldFlipX != this.flipX; - this.worldFlipY = parent.worldFlipY != this.flipY; - } else { - var skeletonFlipX = this.skeleton.flipX, skeletonFlipY = this.skeleton.flipY; - this.worldX = skeletonFlipX ? -this.x : this.x; - this.worldY = (skeletonFlipY != spine.Bone.yDown) ? -this.y : this.y; - this.worldScaleX = this.scaleX; - this.worldScaleY = this.scaleY; - this.worldRotation = this.rotationIK; - this.worldFlipX = skeletonFlipX != this.flipX; - this.worldFlipY = skeletonFlipY != this.flipY; - } - var radians = this.worldRotation * spine.degRad; - var cos = Math.cos(radians); - var sin = Math.sin(radians); - if (this.worldFlipX) { - this.m00 = -cos * this.worldScaleX; - this.m01 = sin * this.worldScaleY; - } else { - this.m00 = cos * this.worldScaleX; - this.m01 = -sin * this.worldScaleY; - } - if (this.worldFlipY != spine.Bone.yDown) { - this.m10 = -sin * this.worldScaleX; - this.m11 = -cos * this.worldScaleY; - } else { - this.m10 = sin * this.worldScaleX; - this.m11 = cos * this.worldScaleY; - } - }, - setToSetupPose: function () { - var data = this.data; - this.x = data.x; - this.y = data.y; - this.rotation = data.rotation; - this.rotationIK = this.rotation; - this.scaleX = data.scaleX; - this.scaleY = data.scaleY; - this.flipX = data.flipX; - this.flipY = data.flipY; - }, - worldToLocal: function (world) { - var dx = world[0] - this.worldX, dy = world[1] - this.worldY; - var m00 = this.m00, m10 = this.m10, m01 = this.m01, m11 = this.m11; - if (this.worldFlipX != (this.worldFlipY != spine.Bone.yDown)) { - m00 = -m00; - m11 = -m11; - } - var invDet = 1 / (m00 * m11 - m01 * m10); - world[0] = dx * m00 * invDet - dy * m01 * invDet; - world[1] = dy * m11 * invDet - dx * m10 * invDet; - }, - localToWorld: function (local) { - var localX = local[0], localY = local[1]; - local[0] = localX * this.m00 + localY * this.m01 + this.worldX; - local[1] = localX * this.m10 + localY * this.m11 + this.worldY; - } -}; - -spine.Slot = function (slotData, bone) { - this.r = this.g = this.b = this.a = 1; - this._attachmentTime = 0; - - this.data = slotData; - this.bone = bone; - this.setToSetupPose(); -}; -spine.Slot.prototype = { - r: 1, g: 1, b: 1, a: 1, - _attachmentTime: 0, - attachment: null, - attachmentVertices: [], - setAttachment: function (attachment) { - this.attachment = attachment; - this._attachmentTime = this.bone.skeleton.time; - this.attachmentVertices.length = 0; - }, - setAttachmentTime: function (time) { - this._attachmentTime = this.bone.skeleton.time - time; - }, - getAttachmentTime: function () { - return this.bone.skeleton.time - this._attachmentTime; - }, - setToSetupPose: function () { - var data = this.data; - this.r = data.r; - this.g = data.g; - this.b = data.b; - this.a = data.a; - - var slotDatas = this.bone.skeleton.data.slots; - for (var i = 0, n = slotDatas.length; i < n; i++) { - if (slotDatas[i] == data) { - this.setAttachment(!data.attachmentName ? null : this.bone.skeleton.getAttachmentBySlotIndex(i, data.attachmentName)); - break; - } - } - } -}; - -spine.IkConstraint = function (data, skeleton) { - this.data = data; - this.mix = data.mix; - this.bendDirection = data.bendDirection; - - this.bones = []; - for (var i = 0, n = data.bones.length; i < n; i++) - this.bones.push(skeleton.findBone(data.bones[i].name)); - this.target = skeleton.findBone(data.target.name); -}; -spine.IkConstraint.prototype = { - apply: function () { - var target = this.target; - var bones = this.bones; - switch (bones.length) { - case 1: - spine.IkConstraint.apply1(bones[0], target.worldX, target.worldY, this.mix); - break; - case 2: - spine.IkConstraint.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.mix); - break; - } - } -}; -/** Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified in the world - * coordinate system. */ -spine.IkConstraint.apply1 = function (bone, targetX, targetY, alpha) { - var parentRotation = (!bone.data.inheritRotation || !bone.parent) ? 0 : bone.parent.worldRotation; - var rotation = bone.rotation; - var rotationIK = Math.atan2(targetY - bone.worldY, targetX - bone.worldX) * spine.radDeg; - if (bone.worldFlipX != (bone.worldFlipY != spine.Bone.yDown)) rotationIK = -rotationIK; - rotationIK -= parentRotation; - bone.rotationIK = rotation + (rotationIK - rotation) * alpha; -}; -/** Adjusts the parent and child bone rotations so the tip of the child is as close to the target position as possible. The - * target is specified in the world coordinate system. - * @param child Any descendant bone of the parent. */ -spine.IkConstraint.apply2 = function (parent, child, targetX, targetY, bendDirection, alpha) { - var childRotation = child.rotation, parentRotation = parent.rotation; - if (!alpha) { - child.rotationIK = childRotation; - parent.rotationIK = parentRotation; - return; - } - var positionX, positionY, tempPosition = spine.temp; - var parentParent = parent.parent; - if (parentParent) { - tempPosition[0] = targetX; - tempPosition[1] = targetY; - parentParent.worldToLocal(tempPosition); - targetX = (tempPosition[0] - parent.x) * parentParent.worldScaleX; - targetY = (tempPosition[1] - parent.y) * parentParent.worldScaleY; - } else { - targetX -= parent.x; - targetY -= parent.y; - } - if (child.parent == parent) { - positionX = child.x; - positionY = child.y; - } else { - tempPosition[0] = child.x; - tempPosition[1] = child.y; - child.parent.localToWorld(tempPosition); - parent.worldToLocal(tempPosition); - positionX = tempPosition[0]; - positionY = tempPosition[1]; - } - var childX = positionX * parent.worldScaleX, childY = positionY * parent.worldScaleY; - var offset = Math.atan2(childY, childX); - var len1 = Math.sqrt(childX * childX + childY * childY), len2 = child.data.length * child.worldScaleX; - // Based on code by Ryan Juckett with permission: Copyright (c) 2008-2009 Ryan Juckett, http://www.ryanjuckett.com/ - var cosDenom = 2 * len1 * len2; - if (cosDenom < 0.0001) { - child.rotationIK = childRotation + (Math.atan2(targetY, targetX) * spine.radDeg - parentRotation - childRotation) * alpha; - return; - } - var cos = (targetX * targetX + targetY * targetY - len1 * len1 - len2 * len2) / cosDenom; - if (cos < -1) - cos = -1; - else if (cos > 1) - cos = 1; - var childAngle = Math.acos(cos) * bendDirection; - var adjacent = len1 + len2 * cos, opposite = len2 * Math.sin(childAngle); - var parentAngle = Math.atan2(targetY * adjacent - targetX * opposite, targetX * adjacent + targetY * opposite); - var rotation = (parentAngle - offset) * spine.radDeg - parentRotation; - if (rotation > 180) - rotation -= 360; - else if (rotation < -180) // - rotation += 360; - parent.rotationIK = parentRotation + rotation * alpha; - rotation = (childAngle + offset) * spine.radDeg - childRotation; - if (rotation > 180) - rotation -= 360; - else if (rotation < -180) // - rotation += 360; - child.rotationIK = childRotation + (rotation + parent.worldRotation - child.parent.worldRotation) * alpha; -}; - -spine.Skin = function (name) { - this.name = name; - this.attachments = {}; -}; -spine.Skin.prototype = { - addAttachment: function (slotIndex, name, attachment) { - this.attachments[slotIndex + ":" + name] = attachment; - }, - getAttachment: function (slotIndex, name) { - return this.attachments[slotIndex + ":" + name]; - }, - _attachAll: function (skeleton, oldSkin) { - for (var key in oldSkin.attachments) { - var colon = key.indexOf(":"); - var slotIndex = parseInt(key.substring(0, colon)); - var name = key.substring(colon + 1); - var slot = skeleton.slots[slotIndex]; - if (slot.attachment && slot.attachment.name == name) { - var attachment = this.getAttachment(slotIndex, name); - if (attachment) slot.setAttachment(attachment); - } - } - } -}; - -spine.Animation = function (name, timelines, duration) { - this.name = name; - this.timelines = timelines; - this.duration = duration; -}; -spine.Animation.prototype = { - apply: function (skeleton, lastTime, time, loop, events) { - if (loop && this.duration != 0) { - time %= this.duration; - lastTime %= this.duration; - } - var timelines = this.timelines; - for (var i = 0, n = timelines.length; i < n; i++) - timelines[i].apply(skeleton, lastTime, time, events, 1); - }, - mix: function (skeleton, lastTime, time, loop, events, alpha) { - if (loop && this.duration != 0) { - time %= this.duration; - lastTime %= this.duration; - } - var timelines = this.timelines; - for (var i = 0, n = timelines.length; i < n; i++) - timelines[i].apply(skeleton, lastTime, time, events, alpha); - } -}; -spine.Animation.binarySearch = function (values, target, step) { - var low = 0; - var high = Math.floor(values.length / step) - 2; - if (!high) return step; - var current = high >>> 1; - while (true) { - if (values[(current + 1) * step] <= target) - low = current + 1; - else - high = current; - if (low == high) return (low + 1) * step; - current = (low + high) >>> 1; - } -}; -spine.Animation.binarySearch1 = function (values, target) { - var low = 0; - var high = values.length - 2; - if (!high) return 1; - var current = high >>> 1; - while (true) { - if (values[current + 1] <= target) - low = current + 1; - else - high = current; - if (low == high) return low + 1; - current = (low + high) >>> 1; - } -}; -spine.Animation.linearSearch = function (values, target, step) { - for (var i = 0, last = values.length - step; i <= last; i += step) - if (values[i] > target) return i; - return -1; -}; - -spine.Curves = function (frameCount) { - this.curves = []; // type, x, y, ... - //this.curves.length = (frameCount - 1) * 19/*BEZIER_SIZE*/; -}; -spine.Curves.prototype = { - setLinear: function (frameIndex) { - this.curves[frameIndex * 19/*BEZIER_SIZE*/] = 0/*LINEAR*/; - }, - setStepped: function (frameIndex) { - this.curves[frameIndex * 19/*BEZIER_SIZE*/] = 1/*STEPPED*/; - }, - /** Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next. - * cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of - * the difference between the keyframe's values. */ - setCurve: function (frameIndex, cx1, cy1, cx2, cy2) { - var subdiv1 = 1 / 10/*BEZIER_SEGMENTS*/, subdiv2 = subdiv1 * subdiv1, subdiv3 = subdiv2 * subdiv1; - var pre1 = 3 * subdiv1, pre2 = 3 * subdiv2, pre4 = 6 * subdiv2, pre5 = 6 * subdiv3; - var tmp1x = -cx1 * 2 + cx2, tmp1y = -cy1 * 2 + cy2, tmp2x = (cx1 - cx2) * 3 + 1, tmp2y = (cy1 - cy2) * 3 + 1; - var dfx = cx1 * pre1 + tmp1x * pre2 + tmp2x * subdiv3, dfy = cy1 * pre1 + tmp1y * pre2 + tmp2y * subdiv3; - var ddfx = tmp1x * pre4 + tmp2x * pre5, ddfy = tmp1y * pre4 + tmp2y * pre5; - var dddfx = tmp2x * pre5, dddfy = tmp2y * pre5; - - var i = frameIndex * 19/*BEZIER_SIZE*/; - var curves = this.curves; - curves[i++] = 2/*BEZIER*/; - - var x = dfx, y = dfy; - for (var n = i + 19/*BEZIER_SIZE*/ - 1; i < n; i += 2) { - curves[i] = x; - curves[i + 1] = y; - dfx += ddfx; - dfy += ddfy; - ddfx += dddfx; - ddfy += dddfy; - x += dfx; - y += dfy; - } - }, - getCurvePercent: function (frameIndex, percent) { - percent = percent < 0 ? 0 : (percent > 1 ? 1 : percent); - var curves = this.curves; - var i = frameIndex * 19/*BEZIER_SIZE*/; - var type = curves[i]; - if (type === 0/*LINEAR*/) return percent; - if (type == 1/*STEPPED*/) return 0; - i++; - var x = 0; - for (var start = i, n = i + 19/*BEZIER_SIZE*/ - 1; i < n; i += 2) { - x = curves[i]; - if (x >= percent) { - var prevX, prevY; - if (i == start) { - prevX = 0; - prevY = 0; - } else { - prevX = curves[i - 2]; - prevY = curves[i - 1]; - } - return prevY + (curves[i + 1] - prevY) * (percent - prevX) / (x - prevX); - } - } - var y = curves[i - 1]; - return y + (1 - y) * (percent - x) / (1 - x); // Last point is 1,1. - } -}; - -spine.RotateTimeline = function (frameCount) { - this.boneIndex = 0; - - this.curves = new spine.Curves(frameCount); - this.frames = []; // time, angle, ... - this.frames.length = frameCount * 2; -}; -spine.RotateTimeline.prototype = { - boneIndex: 0, - getFrameCount: function () { - return this.frames.length / 2; - }, - setFrame: function (frameIndex, time, angle) { - frameIndex *= 2; - this.frames[frameIndex] = time; - this.frames[frameIndex + 1] = angle; - }, - apply: function (skeleton, lastTime, time, firedEvents, alpha) { - var frames = this.frames; - if (time < frames[0]) return; // Time is before first frame. - - var bone = skeleton.bones[this.boneIndex]; - - if (time >= frames[frames.length - 2]) { // Time is after last frame. - var amount = bone.data.rotation + frames[frames.length - 1] - bone.rotation; - while (amount > 180) - amount -= 360; - while (amount < -180) - amount += 360; - bone.rotation += amount * alpha; - return; - } - - // Interpolate between the previous frame and the current frame. - var frameIndex = spine.Animation.binarySearch(frames, time, 2); - var prevFrameValue = frames[frameIndex - 1]; - var frameTime = frames[frameIndex]; - var percent = 1 - (time - frameTime) / (frames[frameIndex - 2/*PREV_FRAME_TIME*/] - frameTime); - percent = this.curves.getCurvePercent(frameIndex / 2 - 1, percent); - - var amount = frames[frameIndex + 1/*FRAME_VALUE*/] - prevFrameValue; - while (amount > 180) - amount -= 360; - while (amount < -180) - amount += 360; - amount = bone.data.rotation + (prevFrameValue + amount * percent) - bone.rotation; - while (amount > 180) - amount -= 360; - while (amount < -180) - amount += 360; - bone.rotation += amount * alpha; - } -}; - -spine.TranslateTimeline = function (frameCount) { - this.boneIndex = 0; - - this.curves = new spine.Curves(frameCount); - this.frames = []; // time, x, y, ... - this.frames.length = frameCount * 3; -}; -spine.TranslateTimeline.prototype = { - boneIndex: 0, - getFrameCount: function () { - return this.frames.length / 3; - }, - setFrame: function (frameIndex, time, x, y) { - frameIndex *= 3; - this.frames[frameIndex] = time; - this.frames[frameIndex + 1] = x; - this.frames[frameIndex + 2] = y; - }, - apply: function (skeleton, lastTime, time, firedEvents, alpha) { - var frames = this.frames; - if (time < frames[0]) return; // Time is before first frame. - - var bone = skeleton.bones[this.boneIndex]; - - if (time >= frames[frames.length - 3]) { // Time is after last frame. - bone.x += (bone.data.x + frames[frames.length - 2] - bone.x) * alpha; - bone.y += (bone.data.y + frames[frames.length - 1] - bone.y) * alpha; - return; - } - - // Interpolate between the previous frame and the current frame. - var frameIndex = spine.Animation.binarySearch(frames, time, 3); - var prevFrameX = frames[frameIndex - 2]; - var prevFrameY = frames[frameIndex - 1]; - var frameTime = frames[frameIndex]; - var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*PREV_FRAME_TIME*/] - frameTime); - percent = this.curves.getCurvePercent(frameIndex / 3 - 1, percent); - - bone.x += (bone.data.x + prevFrameX + (frames[frameIndex + 1/*FRAME_X*/] - prevFrameX) * percent - bone.x) * alpha; - bone.y += (bone.data.y + prevFrameY + (frames[frameIndex + 2/*FRAME_Y*/] - prevFrameY) * percent - bone.y) * alpha; - } -}; - -spine.ScaleTimeline = function (frameCount) { - this.boneIndex = 0; - - this.curves = new spine.Curves(frameCount); - this.frames = []; // time, x, y, ... - this.frames.length = frameCount * 3; -}; -spine.ScaleTimeline.prototype = { - boneIndex: 0, - getFrameCount: function () { - return this.frames.length / 3; - }, - setFrame: function (frameIndex, time, x, y) { - frameIndex *= 3; - this.frames[frameIndex] = time; - this.frames[frameIndex + 1] = x; - this.frames[frameIndex + 2] = y; - }, - apply: function (skeleton, lastTime, time, firedEvents, alpha) { - var frames = this.frames; - if (time < frames[0]) return; // Time is before first frame. - - var bone = skeleton.bones[this.boneIndex]; - - if (time >= frames[frames.length - 3]) { // Time is after last frame. - bone.scaleX += (bone.data.scaleX * frames[frames.length - 2] - bone.scaleX) * alpha; - bone.scaleY += (bone.data.scaleY * frames[frames.length - 1] - bone.scaleY) * alpha; - return; - } - - // Interpolate between the previous frame and the current frame. - var frameIndex = spine.Animation.binarySearch(frames, time, 3); - var prevFrameX = frames[frameIndex - 2]; - var prevFrameY = frames[frameIndex - 1]; - var frameTime = frames[frameIndex]; - var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*PREV_FRAME_TIME*/] - frameTime); - percent = this.curves.getCurvePercent(frameIndex / 3 - 1, percent); - - bone.scaleX += (bone.data.scaleX * (prevFrameX + (frames[frameIndex + 1/*FRAME_X*/] - prevFrameX) * percent) - bone.scaleX) * alpha; - bone.scaleY += (bone.data.scaleY * (prevFrameY + (frames[frameIndex + 2/*FRAME_Y*/] - prevFrameY) * percent) - bone.scaleY) * alpha; - } -}; - -spine.ColorTimeline = function (frameCount) { - this.boneIndex = 0; - - this.curves = new spine.Curves(frameCount); - this.frames = []; // time, r, g, b, a, ... - this.frames.length = frameCount * 5; -}; -spine.ColorTimeline.prototype = { - slotIndex: 0, - getFrameCount: function () { - return this.frames.length / 5; - }, - setFrame: function (frameIndex, time, r, g, b, a) { - frameIndex *= 5; - this.frames[frameIndex] = time; - this.frames[frameIndex + 1] = r; - this.frames[frameIndex + 2] = g; - this.frames[frameIndex + 3] = b; - this.frames[frameIndex + 4] = a; - }, - apply: function (skeleton, lastTime, time, firedEvents, alpha) { - var frames = this.frames; - if (time < frames[0]) return; // Time is before first frame. - - var r, g, b, a; - if (time >= frames[frames.length - 5]) { - // Time is after last frame. - var i = frames.length - 1; - r = frames[i - 3]; - g = frames[i - 2]; - b = frames[i - 1]; - a = frames[i]; - } else { - // Interpolate between the previous frame and the current frame. - var frameIndex = spine.Animation.binarySearch(frames, time, 5); - var prevFrameR = frames[frameIndex - 4]; - var prevFrameG = frames[frameIndex - 3]; - var prevFrameB = frames[frameIndex - 2]; - var prevFrameA = frames[frameIndex - 1]; - var frameTime = frames[frameIndex]; - var percent = 1 - (time - frameTime) / (frames[frameIndex - 5/*PREV_FRAME_TIME*/] - frameTime); - percent = this.curves.getCurvePercent(frameIndex / 5 - 1, percent); - - r = prevFrameR + (frames[frameIndex + 1/*FRAME_R*/] - prevFrameR) * percent; - g = prevFrameG + (frames[frameIndex + 2/*FRAME_G*/] - prevFrameG) * percent; - b = prevFrameB + (frames[frameIndex + 3/*FRAME_B*/] - prevFrameB) * percent; - a = prevFrameA + (frames[frameIndex + 4/*FRAME_A*/] - prevFrameA) * percent; - } - var slot = skeleton.slots[this.slotIndex]; - if (alpha < 1) { - slot.r += (r - slot.r) * alpha; - slot.g += (g - slot.g) * alpha; - slot.b += (b - slot.b) * alpha; - slot.a += (a - slot.a) * alpha; - } else { - slot.r = r; - slot.g = g; - slot.b = b; - slot.a = a; - } - } -}; - -spine.AttachmentTimeline = function (frameCount) { - this.slotIndex = 0; - - this.curves = new spine.Curves(frameCount); - this.frames = []; // time, ... - this.frames.length = frameCount; - this.attachmentNames = []; - this.attachmentNames.length = frameCount; -}; -spine.AttachmentTimeline.prototype = { - slotIndex: 0, - getFrameCount: function () { - return this.frames.length; - }, - setFrame: function (frameIndex, time, attachmentName) { - this.frames[frameIndex] = time; - this.attachmentNames[frameIndex] = attachmentName; - }, - apply: function (skeleton, lastTime, time, firedEvents, alpha) { - var frames = this.frames; - if (time < frames[0]) { - if (lastTime > time) this.apply(skeleton, lastTime, Number.MAX_VALUE, null, 0); - return; - } else if (lastTime > time) // - lastTime = -1; - - var frameIndex = time >= frames[frames.length - 1] ? frames.length - 1 : spine.Animation.binarySearch1(frames, time) - 1; - if (frames[frameIndex] < lastTime) return; - - var attachmentName = this.attachmentNames[frameIndex]; - skeleton.slots[this.slotIndex].setAttachment( - !attachmentName ? null : skeleton.getAttachmentBySlotIndex(this.slotIndex, attachmentName)); - } -}; - -spine.EventTimeline = function (frameCount) { - this.frames = []; // time, ... - this.frames.length = frameCount; - this.events = []; - this.events.length = frameCount; -}; -spine.EventTimeline.prototype = { - getFrameCount: function () { - return this.frames.length; - }, - setFrame: function (frameIndex, time, event) { - this.frames[frameIndex] = time; - this.events[frameIndex] = event; - }, - /** Fires events for frames > lastTime and <= time. */ - apply: function (skeleton, lastTime, time, firedEvents, alpha) { - if (!firedEvents) return; - - var frames = this.frames; - var frameCount = frames.length; - - if (lastTime > time) { // Fire events after last time for looped animations. - this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha); - lastTime = -1; - } else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame. - return; - if (time < frames[0]) return; // Time is before first frame. - - var frameIndex; - if (lastTime < frames[0]) - frameIndex = 0; - else { - frameIndex = spine.Animation.binarySearch1(frames, lastTime); - var frame = frames[frameIndex]; - while (frameIndex > 0) { // Fire multiple events with the same frame. - if (frames[frameIndex - 1] != frame) break; - frameIndex--; - } - } - var events = this.events; - for (; frameIndex < frameCount && time >= frames[frameIndex]; frameIndex++) - firedEvents.push(events[frameIndex]); - } -}; - -spine.DrawOrderTimeline = function (frameCount) { - this.frames = []; // time, ... - this.frames.length = frameCount; - this.drawOrders = []; - this.drawOrders.length = frameCount; -}; -spine.DrawOrderTimeline.prototype = { - getFrameCount: function () { - return this.frames.length; - }, - setFrame: function (frameIndex, time, drawOrder) { - this.frames[frameIndex] = time; - this.drawOrders[frameIndex] = drawOrder; - }, - apply: function (skeleton, lastTime, time, firedEvents, alpha) { - var frames = this.frames; - if (time < frames[0]) return; // Time is before first frame. - - var frameIndex; - if (time >= frames[frames.length - 1]) // Time is after last frame. - frameIndex = frames.length - 1; - else - frameIndex = spine.Animation.binarySearch1(frames, time) - 1; - - var drawOrder = skeleton.drawOrder; - var slots = skeleton.slots; - var drawOrderToSetupIndex = this.drawOrders[frameIndex]; - if (!drawOrderToSetupIndex) { - for (var i = 0, n = slots.length; i < n; i++) - drawOrder[i] = slots[i]; - } else { - for (var i = 0, n = drawOrderToSetupIndex.length; i < n; i++) - drawOrder[i] = skeleton.slots[drawOrderToSetupIndex[i]]; - } - - } -}; - -spine.FfdTimeline = function (frameCount) { - this.slotIndex = this.attachment = 0; - - this.curves = new spine.Curves(frameCount); - this.frames = []; - this.frames.length = frameCount; - this.frameVertices = []; - this.frameVertices.length = frameCount; -}; -spine.FfdTimeline.prototype = { - slotIndex: 0, - attachment: 0, - getFrameCount: function () { - return this.frames.length; - }, - setFrame: function (frameIndex, time, vertices) { - this.frames[frameIndex] = time; - this.frameVertices[frameIndex] = vertices; - }, - apply: function (skeleton, lastTime, time, firedEvents, alpha) { - var slot = skeleton.slots[this.slotIndex]; - if (slot.attachment != this.attachment) return; - - var frames = this.frames; - if (time < frames[0]) return; // Time is before first frame. - - var frameVertices = this.frameVertices; - var vertexCount = frameVertices[0].length; - - var vertices = slot.attachmentVertices; - if (vertices.length != vertexCount) alpha = 1; - vertices.length = vertexCount; - - if (time >= frames[frames.length - 1]) { // Time is after last frame. - var lastVertices = frameVertices[frames.length - 1]; - if (alpha < 1) { - for (var i = 0; i < vertexCount; i++) - vertices[i] += (lastVertices[i] - vertices[i]) * alpha; - } else { - for (var i = 0; i < vertexCount; i++) - vertices[i] = lastVertices[i]; - } - return; - } - - // Interpolate between the previous frame and the current frame. - var frameIndex = spine.Animation.binarySearch1(frames, time); - var frameTime = frames[frameIndex]; - var percent = 1 - (time - frameTime) / (frames[frameIndex - 1] - frameTime); - percent = this.curves.getCurvePercent(frameIndex - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent)); - - var prevVertices = frameVertices[frameIndex - 1]; - var nextVertices = frameVertices[frameIndex]; - - if (alpha < 1) { - for (var i = 0; i < vertexCount; i++) { - var prev = prevVertices[i]; - vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha; - } - } else { - for (var i = 0; i < vertexCount; i++) { - var prev = prevVertices[i]; - vertices[i] = prev + (nextVertices[i] - prev) * percent; - } - } - } -}; - -spine.IkConstraintTimeline = function (frameCount) { - this.ikConstraintIndex = 0; - - this.curves = new spine.Curves(frameCount); - this.frames = []; // time, mix, bendDirection, ... - this.frames.length = frameCount * 3; -}; -spine.IkConstraintTimeline.prototype = { - ikConstraintIndex: 0, - getFrameCount: function () { - return this.frames.length / 3; - }, - setFrame: function (frameIndex, time, mix, bendDirection) { - frameIndex *= 3; - this.frames[frameIndex] = time; - this.frames[frameIndex + 1] = mix; - this.frames[frameIndex + 2] = bendDirection; - }, - apply: function (skeleton, lastTime, time, firedEvents, alpha) { - var frames = this.frames; - if (time < frames[0]) return; // Time is before first frame. - - var ikConstraint = skeleton.ikConstraints[this.ikConstraintIndex]; - - if (time >= frames[frames.length - 3]) { // Time is after last frame. - ikConstraint.mix += (frames[frames.length - 2] - ikConstraint.mix) * alpha; - ikConstraint.bendDirection = frames[frames.length - 1]; - return; - } - - // Interpolate between the previous frame and the current frame. - var frameIndex = spine.Animation.binarySearch(frames, time, 3); - var prevFrameMix = frames[frameIndex + -2/*PREV_FRAME_MIX*/]; - var frameTime = frames[frameIndex]; - var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*PREV_FRAME_TIME*/] - frameTime); - percent = this.curves.getCurvePercent(frameIndex / 3 - 1, percent); - - var mix = prevFrameMix + (frames[frameIndex + 1/*FRAME_MIX*/] - prevFrameMix) * percent; - ikConstraint.mix += (mix - ikConstraint.mix) * alpha; - ikConstraint.bendDirection = frames[frameIndex + -1/*PREV_FRAME_BEND_DIRECTION*/]; - } -}; - -spine.FlipXTimeline = function (frameCount) { - this.boneIndex = 0; - - this.curves = new spine.Curves(frameCount); - this.frames = []; // time, flip, ... - this.frames.length = frameCount * 2; -}; -spine.FlipXTimeline.prototype = { - boneIndex: 0, - getFrameCount: function () { - return this.frames.length / 2; - }, - setFrame: function (frameIndex, time, flip) { - frameIndex *= 2; - this.frames[frameIndex] = time; - this.frames[frameIndex + 1] = flip ? 1 : 0; - }, - apply: function (skeleton, lastTime, time, firedEvents, alpha) { - var frames = this.frames; - if (time < frames[0]) { - if (lastTime > time) this.apply(skeleton, lastTime, Number.MAX_VALUE, null, 0); - return; - } else if (lastTime > time) // - lastTime = -1; - var frameIndex = (time >= frames[frames.length - 2] ? frames.length : spine.Animation.binarySearch(frames, time, 2)) - 2; - if (frames[frameIndex] < lastTime) return; - skeleton.bones[this.boneIndex].flipX = frames[frameIndex + 1] != 0; - } -}; - -spine.FlipYTimeline = function (frameCount) { - this.boneIndex = 0; - - this.curves = new spine.Curves(frameCount); - this.frames = []; // time, flip, ... - this.frames.length = frameCount * 2; -}; -spine.FlipYTimeline.prototype = { - boneIndex: 0, - getFrameCount: function () { - return this.frames.length / 2; - }, - setFrame: function (frameIndex, time, flip) { - frameIndex *= 2; - this.frames[frameIndex] = time; - this.frames[frameIndex + 1] = flip ? 1 : 0; - }, - apply: function (skeleton, lastTime, time, firedEvents, alpha) { - var frames = this.frames; - if (time < frames[0]) { - if (lastTime > time) this.apply(skeleton, lastTime, Number.MAX_VALUE, null, 0); - return; - } else if (lastTime > time) // - lastTime = -1; - var frameIndex = (time >= frames[frames.length - 2] ? frames.length : spine.Animation.binarySearch(frames, time, 2)) - 2; - if (frames[frameIndex] < lastTime) return; - skeleton.bones[this.boneIndex].flipY = frames[frameIndex + 1] != 0; - } -}; - -spine.SkeletonData = function () { - this.width = this.height = 0; - - this.bones = []; - this.slots = []; - this.skins = []; - this.events = []; - this.animations = []; - this.ikConstraints = []; -}; -spine.SkeletonData.prototype = { - name: null, - defaultSkin: null, - width: 0, height: 0, - version: null, hash: null, - /** @return May be null. */ - findBone: function (boneName) { - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - if (bones[i].name == boneName) return bones[i]; - return null; - }, - /** @return -1 if the bone was not found. */ - findBoneIndex: function (boneName) { - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - if (bones[i].name == boneName) return i; - return -1; - }, - /** @return May be null. */ - findSlot: function (slotName) { - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) { - if (slots[i].name == slotName) return slot[i]; - } - return null; - }, - /** @return -1 if the bone was not found. */ - findSlotIndex: function (slotName) { - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) - if (slots[i].name == slotName) return i; - return -1; - }, - /** @return May be null. */ - findSkin: function (skinName) { - var skins = this.skins; - for (var i = 0, n = skins.length; i < n; i++) - if (skins[i].name == skinName) return skins[i]; - return null; - }, - /** @return May be null. */ - findEvent: function (eventName) { - var events = this.events; - for (var i = 0, n = events.length; i < n; i++) - if (events[i].name == eventName) return events[i]; - return null; - }, - /** @return May be null. */ - findAnimation: function (animationName) { - var animations = this.animations; - for (var i = 0, n = animations.length; i < n; i++) - if (animations[i].name == animationName) return animations[i]; - return null; - }, - /** @return May be null. */ - findIkConstraint: function (ikConstraintName) { - var ikConstraints = this.ikConstraints; - for (var i = 0, n = ikConstraints.length; i < n; i++) - if (ikConstraints[i].name == ikConstraintName) return ikConstraints[i]; - return null; - } -}; - -spine.Skeleton = function (skeletonData) { - this.x = this.y = 0; - this.r = this.g = this.b = this.a = 1; - this.time = 0; - this.flipX = this.flipY = false; - - this.data = skeletonData; - - this.bones = []; - for (var i = 0, n = skeletonData.bones.length; i < n; i++) { - var boneData = skeletonData.bones[i]; - var parent = !boneData.parent ? null : this.bones[skeletonData.bones.indexOf(boneData.parent)]; - this.bones.push(new spine.Bone(boneData, this, parent)); - } - - this.slots = []; - this.drawOrder = []; - for (var i = 0, n = skeletonData.slots.length; i < n; i++) { - var slotData = skeletonData.slots[i]; - var bone = this.bones[skeletonData.bones.indexOf(slotData.boneData)]; - var slot = new spine.Slot(slotData, bone); - this.slots.push(slot); - this.drawOrder.push(slot); - } - - this.ikConstraints = []; - for (var i = 0, n = skeletonData.ikConstraints.length; i < n; i++) - this.ikConstraints.push(new spine.IkConstraint(skeletonData.ikConstraints[i], this)); - - this.boneCache = []; - this.updateCache(); -}; -spine.Skeleton.prototype = { - x: 0, y: 0, - skin: null, - r: 1, g: 1, b: 1, a: 1, - time: 0, - flipX: false, flipY: false, - /** Caches information about bones and IK constraints. Must be called if bones or IK constraints are added or removed. */ - updateCache: function () { - var ikConstraints = this.ikConstraints; - var ikConstraintsCount = ikConstraints.length; - - var arrayCount = ikConstraintsCount + 1; - var boneCache = this.boneCache; - if (boneCache.length > arrayCount) boneCache.length = arrayCount; - for (var i = 0, n = boneCache.length; i < n; i++) - boneCache[i].length = 0; - while (boneCache.length < arrayCount) - boneCache[boneCache.length] = []; - - var nonIkBones = boneCache[0]; - var bones = this.bones; - - outer: - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - var current = bone; - do { - for (var ii = 0; ii < ikConstraintsCount; ii++) { - var ikConstraint = ikConstraints[ii]; - var parent = ikConstraint.bones[0]; - var child= ikConstraint.bones[ikConstraint.bones.length - 1]; - while (true) { - if (current == child) { - boneCache[ii].push(bone); - boneCache[ii + 1].push(bone); - continue outer; - } - if (child == parent) break; - child = child.parent; - } - } - current = current.parent; - } while (current); - nonIkBones[nonIkBones.length] = bone; - } - }, - /** Updates the world transform for each bone. */ - updateWorldTransform: function () { - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) { - var bone = bones[i]; - bone.rotationIK = bone.rotation; - } - var i = 0, last = this.boneCache.length - 1; - while (true) { - var cacheBones = this.boneCache[i]; - for (var ii = 0, nn = cacheBones.length; ii < nn; ii++) - cacheBones[ii].updateWorldTransform(); - if (i == last) break; - this.ikConstraints[i].apply(); - i++; - } - }, - /** Sets the bones and slots to their setup pose values. */ - setToSetupPose: function () { - this.setBonesToSetupPose(); - this.setSlotsToSetupPose(); - }, - setBonesToSetupPose: function () { - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - bones[i].setToSetupPose(); - - var ikConstraints = this.ikConstraints; - for (var i = 0, n = ikConstraints.length; i < n; i++) { - var ikConstraint = ikConstraints[i]; - ikConstraint.bendDirection = ikConstraint.data.bendDirection; - ikConstraint.mix = ikConstraint.data.mix; - } - }, - setSlotsToSetupPose: function () { - var slots = this.slots; - var drawOrder = this.drawOrder; - for (var i = 0, n = slots.length; i < n; i++) { - drawOrder[i] = slots[i]; - slots[i].setToSetupPose(i); - } - }, - /** @return May return null. */ - getRootBone: function () { - return this.bones.length ? this.bones[0] : null; - }, - /** @return May be null. */ - findBone: function (boneName) { - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - if (bones[i].data.name == boneName) return bones[i]; - return null; - }, - /** @return -1 if the bone was not found. */ - findBoneIndex: function (boneName) { - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - if (bones[i].data.name == boneName) return i; - return -1; - }, - /** @return May be null. */ - findSlot: function (slotName) { - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) - if (slots[i].data.name == slotName) return slots[i]; - return null; - }, - /** @return -1 if the bone was not found. */ - findSlotIndex: function (slotName) { - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) - if (slots[i].data.name == slotName) return i; - return -1; - }, - setSkinByName: function (skinName) { - var skin = this.data.findSkin(skinName); - if (!skin) throw new Error("Skin not found: " + skinName); - this.setSkin(skin); - }, - /** Sets the skin used to look up attachments before looking in the {@link SkeletonData#getDefaultSkin() default skin}. - * Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was - * no old skin, each slot's setup mode attachment is attached from the new skin. - * @param newSkin May be null. */ - setSkin: function (newSkin) { - if (newSkin) { - if (this.skin) - newSkin._attachAll(this, this.skin); - else { - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) { - var slot = slots[i]; - var name = slot.data.attachmentName; - if (name) { - var attachment = newSkin.getAttachment(i, name); - if (attachment) slot.setAttachment(attachment); - } - } - } - } - this.skin = newSkin; - }, - /** @return May be null. */ - getAttachmentBySlotName: function (slotName, attachmentName) { - return this.getAttachmentBySlotIndex(this.data.findSlotIndex(slotName), attachmentName); - }, - /** @return May be null. */ - getAttachmentBySlotIndex: function (slotIndex, attachmentName) { - if (this.skin) { - var attachment = this.skin.getAttachment(slotIndex, attachmentName); - if (attachment) return attachment; - } - if (this.data.defaultSkin) return this.data.defaultSkin.getAttachment(slotIndex, attachmentName); - return null; - }, - /** @param attachmentName May be null. */ - setAttachment: function (slotName, attachmentName) { - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) { - var slot = slots[i]; - if (slot.data.name == slotName) { - var attachment = null; - if (attachmentName) { - attachment = this.getAttachmentBySlotIndex(i, attachmentName); - if (!attachment) throw new Error("Attachment not found: " + attachmentName + ", for slot: " + slotName); - } - slot.setAttachment(attachment); - return; - } - } - throw new Error("Slot not found: " + slotName); - }, - /** @return May be null. */ - findIkConstraint: function (ikConstraintName) { - var ikConstraints = this.ikConstraints; - for (var i = 0, n = ikConstraints.length; i < n; i++) - if (ikConstraints[i].data.name == ikConstraintName) return ikConstraints[i]; - return null; - }, - update: function (delta) { - this.time += delta; - } -}; - -spine.EventData = function (name) { - this.intValue = this.floatValue = 0; - - this.name = name; -}; -spine.EventData.prototype = { - intValue: 0, - floatValue: 0, - stringValue: null -}; - -spine.Event = function (data) { - this.intValue = this.floatValue = 0; - - this.data = data; -}; -spine.Event.prototype = { - intValue: 0, - floatValue: 0, - stringValue: null -}; - -spine.AttachmentType = { - region: 0, - boundingbox: 1, - mesh: 2, - skinnedmesh: 3 -}; - -spine.RegionAttachment = function (name) { - this.type = spine.AttachmentType.region; - this.x = this.y = this.rotation = 0; - this.scaleX = this.scaleY = 1; - this.width = this.height = 0; - this.r = this.g = this.b = this.a = 1; - this.regionOffsetX = this.regionOffsetY = this.regionWidth = this.regionHeight = this.regionOriginalWidth = this.regionOriginalHeight = 0; - - this.name = name; - this.offset = []; - this.offset.length = 8; - this.uvs = []; - this.uvs.length = 8; -}; -spine.RegionAttachment.prototype = { - x: 0, y: 0, - rotation: 0, - scaleX: 1, scaleY: 1, - width: 0, height: 0, - r: 1, g: 1, b: 1, a: 1, - path: null, - rendererObject: null, - regionOffsetX: 0, regionOffsetY: 0, - regionWidth: 0, regionHeight: 0, - regionOriginalWidth: 0, regionOriginalHeight: 0, - setUVs: function (u, v, u2, v2, rotate) { - var uvs = this.uvs; - if (rotate) { - uvs[2/*X2*/] = u; - uvs[3/*Y2*/] = v2; - uvs[4/*X3*/] = u; - uvs[5/*Y3*/] = v; - uvs[6/*X4*/] = u2; - uvs[7/*Y4*/] = v; - uvs[0/*X1*/] = u2; - uvs[1/*Y1*/] = v2; - } else { - uvs[0/*X1*/] = u; - uvs[1/*Y1*/] = v2; - uvs[2/*X2*/] = u; - uvs[3/*Y2*/] = v; - uvs[4/*X3*/] = u2; - uvs[5/*Y3*/] = v; - uvs[6/*X4*/] = u2; - uvs[7/*Y4*/] = v2; - } - }, - updateOffset: function () { - var regionScaleX = this.width / this.regionOriginalWidth * this.scaleX; - var regionScaleY = this.height / this.regionOriginalHeight * this.scaleY; - var localX = -this.width / 2 * this.scaleX + this.regionOffsetX * regionScaleX; - var localY = -this.height / 2 * this.scaleY + this.regionOffsetY * regionScaleY; - var localX2 = localX + this.regionWidth * regionScaleX; - var localY2 = localY + this.regionHeight * regionScaleY; - var radians = this.rotation * spine.degRad; - 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[0/*X1*/] = localXCos - localYSin; - offset[1/*Y1*/] = localYCos + localXSin; - offset[2/*X2*/] = localXCos - localY2Sin; - offset[3/*Y2*/] = localY2Cos + localXSin; - offset[4/*X3*/] = localX2Cos - localY2Sin; - offset[5/*Y3*/] = localY2Cos + localX2Sin; - offset[6/*X4*/] = localX2Cos - localYSin; - offset[7/*Y4*/] = localYCos + localX2Sin; - }, - computeVertices: function (x, y, bone, vertices) { - x += bone.worldX; - y += bone.worldY; - var m00 = bone.m00, m01 = bone.m01, m10 = bone.m10, m11 = bone.m11; - var offset = this.offset; - vertices[0/*X1*/] = offset[0/*X1*/] * m00 + offset[1/*Y1*/] * m01 + x; - vertices[1/*Y1*/] = offset[0/*X1*/] * m10 + offset[1/*Y1*/] * m11 + y; - vertices[2/*X2*/] = offset[2/*X2*/] * m00 + offset[3/*Y2*/] * m01 + x; - vertices[3/*Y2*/] = offset[2/*X2*/] * m10 + offset[3/*Y2*/] * m11 + y; - vertices[4/*X3*/] = offset[4/*X3*/] * m00 + offset[5/*X3*/] * m01 + x; - vertices[5/*X3*/] = offset[4/*X3*/] * m10 + offset[5/*X3*/] * m11 + y; - vertices[6/*X4*/] = offset[6/*X4*/] * m00 + offset[7/*Y4*/] * m01 + x; - vertices[7/*Y4*/] = offset[6/*X4*/] * m10 + offset[7/*Y4*/] * m11 + y; - } -}; - -spine.MeshAttachment = function (name) { - this.type = spine.AttachmentType.mesh; - this.hullLength = 0; - this.r = this.g = this.b = this.a = 1; - this.regionU = this.regionV = this.regionV2 = 0; - this.regionRotate = false; - this.regionOffsetX = this.regionOffsetY = this.regionWidth = this.regionHeight = this.regionOriginalWidth = this.regionOriginalHeight = 0; - this.width = this.height = 0; - - this.name = name; -}; -spine.MeshAttachment.prototype = { - vertices: null, - uvs: null, - regionUVs: null, - triangles: null, - hullLength: 0, - r: 1, g: 1, b: 1, a: 1, - path: null, - rendererObject: null, - regionU: 0, regionV: 0, regionU2: 0, regionV2: 0, regionRotate: false, - regionOffsetX: 0, regionOffsetY: 0, - regionWidth: 0, regionHeight: 0, - regionOriginalWidth: 0, regionOriginalHeight: 0, - edges: null, - width: 0, height: 0, - updateUVs: function () { - var width = this.regionU2 - this.regionU, height = this.regionV2 - this.regionV; - var n = this.regionUVs.length; - if (!this.uvs || this.uvs.length != n) { - this.uvs = new spine.Float32Array(n); - } - if (this.regionRotate) { - for (var i = 0; i < n; i += 2) { - this.uvs[i] = this.regionU + this.regionUVs[i + 1] * width; - this.uvs[i + 1] = this.regionV + height - this.regionUVs[i] * height; - } - } else { - for (var i = 0; i < n; i += 2) { - this.uvs[i] = this.regionU + this.regionUVs[i] * width; - this.uvs[i + 1] = this.regionV + this.regionUVs[i + 1] * height; - } - } - }, - computeWorldVertices: function (x, y, slot, worldVertices) { - var bone = slot.bone; - x += bone.worldX; - y += bone.worldY; - var m00 = bone.m00, m01 = bone.m01, m10 = bone.m10, m11 = bone.m11; - var vertices = this.vertices; - var verticesCount = vertices.length; - if (slot.attachmentVertices.length == verticesCount) vertices = slot.attachmentVertices; - for (var i = 0; i < verticesCount; i += 2) { - var vx = vertices[i]; - var vy = vertices[i + 1]; - worldVertices[i] = vx * m00 + vy * m01 + x; - worldVertices[i + 1] = vx * m10 + vy * m11 + y; - } - } -}; - -spine.SkinnedMeshAttachment = function (name) { - this.type = spine.AttachmentType.skinnedmesh; - this.hullLength = 0; - this.r = this.g = this.b = this.a = 1; - this.regionU = this.regionV = this.regionU2 = this.regionV2 = 0; - this.regionRotate = false; - this.regionOffsetX = this.regionOffsetY = this.regionWidth = this.regionHeight = this.regionOriginalWidth = this.regionOriginalHeight = 0; - this.width = this.height = 0; - - this.name = name; -}; -spine.SkinnedMeshAttachment.prototype = { - bones: null, - weights: null, - uvs: null, - regionUVs: null, - triangles: null, - hullLength: 0, - r: 1, g: 1, b: 1, a: 1, - path: null, - rendererObject: null, - regionU: 0, regionV: 0, regionU2: 0, regionV2: 0, regionRotate: false, - regionOffsetX: 0, regionOffsetY: 0, - regionWidth: 0, regionHeight: 0, - regionOriginalWidth: 0, regionOriginalHeight: 0, - edges: null, - width: 0, height: 0, - updateUVs: function (u, v, u2, v2, rotate) { - var width = this.regionU2 - this.regionU, height = this.regionV2 - this.regionV; - var n = this.regionUVs.length; - if (!this.uvs || this.uvs.length != n) { - this.uvs = new spine.Float32Array(n); - } - if (this.regionRotate) { - for (var i = 0; i < n; i += 2) { - this.uvs[i] = this.regionU + this.regionUVs[i + 1] * width; - this.uvs[i + 1] = this.regionV + height - this.regionUVs[i] * height; - } - } else { - for (var i = 0; i < n; i += 2) { - this.uvs[i] = this.regionU + this.regionUVs[i] * width; - this.uvs[i + 1] = this.regionV + this.regionUVs[i + 1] * height; - } - } - }, - computeWorldVertices: function (x, y, slot, worldVertices) { - var skeletonBones = slot.bone.skeleton.bones; - var weights = this.weights; - var bones = this.bones; - - var w = 0, v = 0, b = 0, f = 0, n = bones.length, nn; - var wx, wy, bone, vx, vy, weight; - if (!slot.attachmentVertices.length) { - for (; v < n; w += 2) { - wx = 0; - wy = 0; - nn = bones[v++] + v; - for (; v < nn; v++, b += 3) { - bone = skeletonBones[bones[v]]; - vx = weights[b]; - vy = weights[b + 1]; - weight = weights[b + 2]; - wx += (vx * bone.m00 + vy * bone.m01 + bone.worldX) * weight; - wy += (vx * bone.m10 + vy * bone.m11 + bone.worldY) * weight; - } - worldVertices[w] = wx + x; - worldVertices[w + 1] = wy + y; - } - } else { - var ffd = slot.attachmentVertices; - for (; v < n; w += 2) { - wx = 0; - wy = 0; - nn = bones[v++] + v; - for (; v < nn; v++, b += 3, f += 2) { - bone = skeletonBones[bones[v]]; - vx = weights[b] + ffd[f]; - vy = weights[b + 1] + ffd[f + 1]; - weight = weights[b + 2]; - wx += (vx * bone.m00 + vy * bone.m01 + bone.worldX) * weight; - wy += (vx * bone.m10 + vy * bone.m11 + bone.worldY) * weight; - } - worldVertices[w] = wx + x; - worldVertices[w + 1] = wy + y; - } - } - } -}; - -spine.BoundingBoxAttachment = function (name) { - this.type = spine.AttachmentType.boundingbox; - - this.name = name; - this.vertices = []; -}; -spine.BoundingBoxAttachment.prototype = { - computeWorldVertices: function (x, y, bone, worldVertices) { - x += bone.worldX; - y += bone.worldY; - var m00 = bone.m00, m01 = bone.m01, m10 = bone.m10, m11 = bone.m11; - var vertices = this.vertices; - for (var i = 0, n = vertices.length; i < n; i += 2) { - var px = vertices[i]; - var py = vertices[i + 1]; - worldVertices[i] = px * m00 + py * m01 + x; - worldVertices[i + 1] = px * m10 + py * m11 + y; - } - } -}; - -spine.AnimationStateData = function (skeletonData) { - this.skeletonData = skeletonData; - this.animationToMixTime = {}; - - this.defaultMix = 0; -}; -spine.AnimationStateData.prototype = { - defaultMix: 0, - setMixByName: function (fromName, toName, duration) { - var from = this.skeletonData.findAnimation(fromName); - if (!from) throw new Error("Animation not found: " + fromName); - var to = this.skeletonData.findAnimation(toName); - if (!to) throw new Error("Animation not found: " + toName); - this.setMix(from, to, duration); - }, - setMix: function (from, to, duration) { - this.animationToMixTime[from.name + ":" + to.name] = duration; - }, - getMix: function (from, to) { - var key = from.name + ":" + to.name; - return this.animationToMixTime.hasOwnProperty(key) ? this.animationToMixTime[key] : this.defaultMix; - } -}; - -spine.TrackEntry = function () { - this.delay = this.time = this.endTime = 0; - this.lastTime = -1; - this.timeScale = 1; - this.mixTime = this.mixDuration = 1; - this.mix = 1; -}; -spine.TrackEntry.prototype = { - next: null, previous: null, - animation: null, - loop: false, - delay: 0, time: 0, lastTime: -1, endTime: 0, - timeScale: 1, - mixTime: 0, mixDuration: 0, mix: 1, - onStart: null, onEnd: null, onComplete: null, onEvent: null -}; - -spine.AnimationState = function (stateData) { - this.timeScale = 1; - - this.data = stateData; - this.tracks = []; - this.events = []; -}; -spine.AnimationState.prototype = { - onStart: null, - onEnd: null, - onComplete: null, - onEvent: null, - timeScale: 1, - update: function (delta) { - delta *= this.timeScale; - for (var i = 0; i < this.tracks.length; i++) { - var current = this.tracks[i]; - if (!current) continue; - - current.time += delta * current.timeScale; - if (current.previous) { - var previousDelta = delta * current.previous.timeScale; - current.previous.time += previousDelta; - current.mixTime += previousDelta; - } - - var next = current.next; - if (next) { - next.time = current.lastTime - next.delay; - if (next.time >= 0) this.setCurrent(i, next); - } else { - // End non-looping animation when it reaches its end time and there is no next entry. - if (!current.loop && current.lastTime >= current.endTime) this.clearTrack(i); - } - } - }, - apply: function (skeleton) { - for (var i = 0; i < this.tracks.length; i++) { - var current = this.tracks[i]; - if (!current) continue; - - this.events.length = 0; - - var time = current.time; - var lastTime = current.lastTime; - var endTime = current.endTime; - var loop = current.loop; - if (!loop && time > endTime) time = endTime; - - var previous = current.previous; - if (!previous) { - if (current.mix == 1) - current.animation.apply(skeleton, current.lastTime, time, loop, this.events); - else - current.animation.mix(skeleton, current.lastTime, time, loop, this.events, current.mix); - } else { - var previousTime = previous.time; - if (!previous.loop && previousTime > previous.endTime) previousTime = previous.endTime; - previous.animation.apply(skeleton, previousTime, previousTime, previous.loop, null); - - var alpha = current.mixTime / current.mixDuration * current.mix; - if (alpha >= 1) { - alpha = 1; - current.previous = null; - } - current.animation.mix(skeleton, current.lastTime, time, loop, this.events, alpha); - } - - for (var ii = 0, nn = this.events.length; ii < nn; ii++) { - var event = this.events[ii]; - if (current.onEvent) current.onEvent(i, event); - if (this.onEvent) this.onEvent(i, event); - } - - // Check if completed the animation or a loop iteration. - if (loop ? (lastTime % endTime > time % endTime) : (lastTime < endTime && time >= endTime)) { - var count = Math.floor(time / endTime); - if (current.onComplete) current.onComplete(i, count); - if (this.onComplete) this.onComplete(i, count); - } - - current.lastTime = current.time; - } - }, - clearTracks: function () { - for (var i = 0, n = this.tracks.length; i < n; i++) - this.clearTrack(i); - this.tracks.length = 0; - }, - clearTrack: function (trackIndex) { - if (trackIndex >= this.tracks.length) return; - var current = this.tracks[trackIndex]; - if (!current) return; - - if (current.onEnd) current.onEnd(trackIndex); - if (this.onEnd) this.onEnd(trackIndex); - - this.tracks[trackIndex] = null; - }, - _expandToIndex: function (index) { - if (index < this.tracks.length) return this.tracks[index]; - while (index >= this.tracks.length) - this.tracks.push(null); - return null; - }, - setCurrent: function (index, entry) { - var current = this._expandToIndex(index); - if (current) { - var previous = current.previous; - current.previous = null; - - if (current.onEnd) current.onEnd(index); - if (this.onEnd) this.onEnd(index); - - entry.mixDuration = this.data.getMix(current.animation, entry.animation); - if (entry.mixDuration > 0) { - entry.mixTime = 0; - // If a mix is in progress, mix from the closest animation. - if (previous && current.mixTime / current.mixDuration < 0.5) - entry.previous = previous; - else - entry.previous = current; - } - } - - this.tracks[index] = entry; - - if (entry.onStart) entry.onStart(index); - if (this.onStart) this.onStart(index); - }, - setAnimationByName: function (trackIndex, animationName, loop) { - var animation = this.data.skeletonData.findAnimation(animationName); - if (!animation) throw new Error("Animation not found: " + animationName); - return this.setAnimation(trackIndex, animation, loop); - }, - /** Set the current animation. Any queued animations are cleared. */ - setAnimation: function (trackIndex, animation, loop) { - var entry = new spine.TrackEntry(); - entry.animation = animation; - entry.loop = loop; - entry.endTime = animation.duration; - this.setCurrent(trackIndex, entry); - return entry; - }, - addAnimationByName: function (trackIndex, animationName, loop, delay) { - var animation = this.data.skeletonData.findAnimation(animationName); - if (!animation) throw new Error("Animation not found: " + animationName); - return this.addAnimation(trackIndex, animation, loop, delay); - }, - /** Adds an animation to be played delay seconds after the current or last queued animation. - * @param delay May be <= 0 to use duration of previous animation minus any mix duration plus the negative delay. */ - addAnimation: function (trackIndex, animation, loop, delay) { - var entry = new spine.TrackEntry(); - entry.animation = animation; - entry.loop = loop; - entry.endTime = animation.duration; - - var last = this._expandToIndex(trackIndex); - if (last) { - while (last.next) - last = last.next; - last.next = entry; - } else - this.tracks[trackIndex] = entry; - - if (delay <= 0) { - if (last) - delay += last.endTime - this.data.getMix(last.animation, animation); - else - delay = 0; - } - entry.delay = delay; - - return entry; - }, - /** May be null. */ - getCurrent: function (trackIndex) { - if (trackIndex >= this.tracks.length) return null; - return this.tracks[trackIndex]; - } -}; - -spine.SkeletonJson = function (attachmentLoader) { - this.scale = 1; - - this.attachmentLoader = attachmentLoader; -}; -spine.SkeletonJson.prototype = { - scale: 1, - readSkeletonData: function (root, name) { - var skeletonData = new spine.SkeletonData(); - skeletonData.name = name; - - // Skeleton. - var skeletonMap = root["skeleton"]; - if (skeletonMap) { - skeletonData.hash = skeletonMap["hash"]; - skeletonData.version = skeletonMap["spine"]; - skeletonData.width = skeletonMap["width"] || 0; - skeletonData.height = skeletonMap["height"] || 0; - } - - // Bones. - var bones = root["bones"]; - for (var i = 0, n = bones.length; i < n; i++) { - var boneMap = bones[i]; - var parent = null; - if (boneMap["parent"]) { - parent = skeletonData.findBone(boneMap["parent"]); - if (!parent) throw new Error("Parent bone not found: " + boneMap["parent"]); - } - var boneData = new spine.BoneData(boneMap["name"], parent); - boneData.length = (boneMap["length"] || 0) * this.scale; - boneData.x = (boneMap["x"] || 0) * this.scale; - boneData.y = (boneMap["y"] || 0) * this.scale; - boneData.rotation = (boneMap["rotation"] || 0); - boneData.scaleX = boneMap.hasOwnProperty("scaleX") ? boneMap["scaleX"] : 1; - boneData.scaleY = boneMap.hasOwnProperty("scaleY") ? boneMap["scaleY"] : 1; - boneData.inheritScale = boneMap.hasOwnProperty("inheritScale") ? boneMap["inheritScale"] : true; - boneData.inheritRotation = boneMap.hasOwnProperty("inheritRotation") ? boneMap["inheritRotation"] : true; - skeletonData.bones.push(boneData); - } - - // IK constraints. - var ik = root["ik"]; - if (ik) { - for (var i = 0, n = ik.length; i < n; i++) { - var ikMap = ik[i]; - var ikConstraintData = new spine.IkConstraintData(ikMap["name"]); - - var bones = ikMap["bones"]; - for (var ii = 0, nn = bones.length; ii < nn; ii++) { - var bone = skeletonData.findBone(bones[ii]); - if (!bone) throw new Error("IK bone not found: " + bones[ii]); - ikConstraintData.bones.push(bone); - } - - ikConstraintData.target = skeletonData.findBone(ikMap["target"]); - if (!ikConstraintData.target) throw new Error("Target bone not found: " + ikMap["target"]); - - ikConstraintData.bendDirection = (!ikMap.hasOwnProperty("bendPositive") || ikMap["bendPositive"]) ? 1 : -1; - ikConstraintData.mix = ikMap.hasOwnProperty("mix") ? ikMap["mix"] : 1; - - skeletonData.ikConstraints.push(ikConstraintData); - } - } - - // Slots. - var slots = root["slots"]; - for (var i = 0, n = slots.length; i < n; i++) { - var slotMap = slots[i]; - var boneData = skeletonData.findBone(slotMap["bone"]); - if (!boneData) throw new Error("Slot bone not found: " + slotMap["bone"]); - var slotData = new spine.SlotData(slotMap["name"], boneData); - - var color = slotMap["color"]; - if (color) { - slotData.r = this.toColor(color, 0); - slotData.g = this.toColor(color, 1); - slotData.b = this.toColor(color, 2); - slotData.a = this.toColor(color, 3); - } - - slotData.attachmentName = slotMap["attachment"]; - slotData.blendMode = spine.AttachmentType[slotMap["blend"] || "normal"]; - - skeletonData.slots.push(slotData); - } - - // Skins. - var skins = root["skins"]; - for (var skinName in skins) { - if (!skins.hasOwnProperty(skinName)) continue; - var skinMap = skins[skinName]; - var skin = new spine.Skin(skinName); - for (var slotName in skinMap) { - if (!skinMap.hasOwnProperty(slotName)) continue; - var slotIndex = skeletonData.findSlotIndex(slotName); - var slotEntry = skinMap[slotName]; - for (var attachmentName in slotEntry) { - if (!slotEntry.hasOwnProperty(attachmentName)) continue; - var attachment = this.readAttachment(skin, attachmentName, slotEntry[attachmentName]); - if (attachment) skin.addAttachment(slotIndex, attachmentName, attachment); - } - } - skeletonData.skins.push(skin); - if (skin.name == "default") skeletonData.defaultSkin = skin; - } - - // Events. - var events = root["events"]; - for (var eventName in events) { - if (!events.hasOwnProperty(eventName)) continue; - var eventMap = events[eventName]; - var eventData = new spine.EventData(eventName); - eventData.intValue = eventMap["int"] || 0; - eventData.floatValue = eventMap["float"] || 0; - eventData.stringValue = eventMap["string"] || null; - skeletonData.events.push(eventData); - } - - // Animations. - var animations = root["animations"]; - for (var animationName in animations) { - if (!animations.hasOwnProperty(animationName)) continue; - this.readAnimation(animationName, animations[animationName], skeletonData); - } - - return skeletonData; - }, - readAttachment: function (skin, name, map) { - name = map["name"] || name; - - var type = spine.AttachmentType[map["type"] || "region"]; - var path = map["path"] || name; - - var scale = this.scale; - if (type == spine.AttachmentType.region) { - var region = this.attachmentLoader.newRegionAttachment(skin, name, path); - if (!region) return null; - region.path = path; - region.x = (map["x"] || 0) * scale; - region.y = (map["y"] || 0) * scale; - region.scaleX = map.hasOwnProperty("scaleX") ? map["scaleX"] : 1; - region.scaleY = map.hasOwnProperty("scaleY") ? map["scaleY"] : 1; - region.rotation = map["rotation"] || 0; - region.width = (map["width"] || 0) * scale; - region.height = (map["height"] || 0) * scale; - - var color = map["color"]; - if (color) { - region.r = this.toColor(color, 0); - region.g = this.toColor(color, 1); - region.b = this.toColor(color, 2); - region.a = this.toColor(color, 3); - } - - region.updateOffset(); - return region; - } else if (type == spine.AttachmentType.mesh) { - var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path); - if (!mesh) return null; - mesh.path = path; - mesh.vertices = this.getFloatArray(map, "vertices", scale); - mesh.triangles = this.getIntArray(map, "triangles"); - mesh.regionUVs = this.getFloatArray(map, "uvs", 1); - mesh.updateUVs(); - - color = map["color"]; - if (color) { - mesh.r = this.toColor(color, 0); - mesh.g = this.toColor(color, 1); - mesh.b = this.toColor(color, 2); - mesh.a = this.toColor(color, 3); - } - - mesh.hullLength = (map["hull"] || 0) * 2; - if (map["edges"]) mesh.edges = this.getIntArray(map, "edges"); - mesh.width = (map["width"] || 0) * scale; - mesh.height = (map["height"] || 0) * scale; - return mesh; - } else if (type == spine.AttachmentType.skinnedmesh) { - var mesh = this.attachmentLoader.newSkinnedMeshAttachment(skin, name, path); - if (!mesh) return null; - mesh.path = path; - - var uvs = this.getFloatArray(map, "uvs", 1); - var vertices = this.getFloatArray(map, "vertices", 1); - var weights = []; - var bones = []; - for (var i = 0, n = vertices.length; i < n; ) { - var boneCount = vertices[i++] | 0; - bones[bones.length] = boneCount; - for (var nn = i + boneCount * 4; i < nn; ) { - bones[bones.length] = vertices[i]; - weights[weights.length] = vertices[i + 1] * scale; - weights[weights.length] = vertices[i + 2] * scale; - weights[weights.length] = vertices[i + 3]; - i += 4; - } - } - mesh.bones = bones; - mesh.weights = weights; - mesh.triangles = this.getIntArray(map, "triangles"); - mesh.regionUVs = uvs; - mesh.updateUVs(); - - color = map["color"]; - if (color) { - mesh.r = this.toColor(color, 0); - mesh.g = this.toColor(color, 1); - mesh.b = this.toColor(color, 2); - mesh.a = this.toColor(color, 3); - } - - mesh.hullLength = (map["hull"] || 0) * 2; - if (map["edges"]) mesh.edges = this.getIntArray(map, "edges"); - mesh.width = (map["width"] || 0) * scale; - mesh.height = (map["height"] || 0) * scale; - return mesh; - } else if (type == spine.AttachmentType.boundingbox) { - var attachment = this.attachmentLoader.newBoundingBoxAttachment(skin, name); - var vertices = map["vertices"]; - for (var i = 0, n = vertices.length; i < n; i++) - attachment.vertices.push(vertices[i] * scale); - return attachment; - } - throw new Error("Unknown attachment type: " + type); - }, - readAnimation: function (name, map, skeletonData) { - var timelines = []; - var duration = 0; - - var slots = map["slots"]; - for (var slotName in slots) { - if (!slots.hasOwnProperty(slotName)) continue; - var slotMap = slots[slotName]; - var slotIndex = skeletonData.findSlotIndex(slotName); - - for (var timelineName in slotMap) { - if (!slotMap.hasOwnProperty(timelineName)) continue; - var values = slotMap[timelineName]; - if (timelineName == "color") { - var timeline = new spine.ColorTimeline(values.length); - timeline.slotIndex = slotIndex; - - var frameIndex = 0; - for (var i = 0, n = values.length; i < n; i++) { - var valueMap = values[i]; - var color = valueMap["color"]; - var r = this.toColor(color, 0); - var g = this.toColor(color, 1); - var b = this.toColor(color, 2); - var a = this.toColor(color, 3); - timeline.setFrame(frameIndex, valueMap["time"], r, g, b, a); - this.readCurve(timeline, frameIndex, valueMap); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 5 - 5]); - - } else if (timelineName == "attachment") { - var timeline = new spine.AttachmentTimeline(values.length); - timeline.slotIndex = slotIndex; - - var frameIndex = 0; - for (var i = 0, n = values.length; i < n; i++) { - var valueMap = values[i]; - timeline.setFrame(frameIndex++, valueMap["time"], valueMap["name"]); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); - - } else - throw new Error("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")"); - } - } - - var bones = map["bones"]; - for (var boneName in bones) { - if (!bones.hasOwnProperty(boneName)) continue; - var boneIndex = skeletonData.findBoneIndex(boneName); - if (boneIndex == -1) throw new Error("Bone not found: " + boneName); - var boneMap = bones[boneName]; - - for (var timelineName in boneMap) { - if (!boneMap.hasOwnProperty(timelineName)) continue; - var values = boneMap[timelineName]; - if (timelineName == "rotate") { - var timeline = new spine.RotateTimeline(values.length); - timeline.boneIndex = boneIndex; - - var frameIndex = 0; - for (var i = 0, n = values.length; i < n; i++) { - var valueMap = values[i]; - timeline.setFrame(frameIndex, valueMap["time"], valueMap["angle"]); - this.readCurve(timeline, frameIndex, valueMap); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 2 - 2]); - - } else if (timelineName == "translate" || timelineName == "scale") { - var timeline; - var timelineScale = 1; - if (timelineName == "scale") - timeline = new spine.ScaleTimeline(values.length); - else { - timeline = new spine.TranslateTimeline(values.length); - timelineScale = this.scale; - } - timeline.boneIndex = boneIndex; - - var frameIndex = 0; - for (var i = 0, n = values.length; i < n; i++) { - var valueMap = values[i]; - var x = (valueMap["x"] || 0) * timelineScale; - var y = (valueMap["y"] || 0) * timelineScale; - timeline.setFrame(frameIndex, valueMap["time"], x, y); - this.readCurve(timeline, frameIndex, valueMap); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 3 - 3]); - - } else if (timelineName == "flipX" || timelineName == "flipY") { - var x = timelineName == "flipX"; - var timeline = x ? new spine.FlipXTimeline(values.length) : new spine.FlipYTimeline(values.length); - timeline.boneIndex = boneIndex; - - var field = x ? "x" : "y"; - var frameIndex = 0; - for (var i = 0, n = values.length; i < n; i++) { - var valueMap = values[i]; - timeline.setFrame(frameIndex, valueMap["time"], valueMap[field] || false); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 2 - 2]); - } else - throw new Error("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")"); - } - } - - var ikMap = map["ik"]; - for (var ikConstraintName in ikMap) { - if (!ikMap.hasOwnProperty(ikConstraintName)) continue; - var ikConstraint = skeletonData.findIkConstraint(ikConstraintName); - var values = ikMap[ikConstraintName]; - var timeline = new spine.IkConstraintTimeline(values.length); - timeline.ikConstraintIndex = skeletonData.ikConstraints.indexOf(ikConstraint); - var frameIndex = 0; - for (var i = 0, n = values.length; i < n; i++) { - var valueMap = values[i]; - var mix = valueMap.hasOwnProperty("mix") ? valueMap["mix"] : 1; - var bendDirection = (!valueMap.hasOwnProperty("bendPositive") || valueMap["bendPositive"]) ? 1 : -1; - timeline.setFrame(frameIndex, valueMap["time"], mix, bendDirection); - this.readCurve(timeline, frameIndex, valueMap); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.frameCount * 3 - 3]); - } - - var ffd = map["ffd"]; - for (var skinName in ffd) { - var skin = skeletonData.findSkin(skinName); - var slotMap = ffd[skinName]; - for (slotName in slotMap) { - var slotIndex = skeletonData.findSlotIndex(slotName); - var meshMap = slotMap[slotName]; - for (var meshName in meshMap) { - var values = meshMap[meshName]; - var timeline = new spine.FfdTimeline(values.length); - var attachment = skin.getAttachment(slotIndex, meshName); - if (!attachment) throw new Error("FFD attachment not found: " + meshName); - timeline.slotIndex = slotIndex; - timeline.attachment = attachment; - - var isMesh = attachment.type == spine.AttachmentType.mesh; - var vertexCount; - if (isMesh) - vertexCount = attachment.vertices.length; - else - vertexCount = attachment.weights.length / 3 * 2; - - var frameIndex = 0; - for (var i = 0, n = values.length; i < n; i++) { - var valueMap = values[i]; - var vertices; - if (!valueMap["vertices"]) { - if (isMesh) - vertices = attachment.vertices; - else { - vertices = []; - vertices.length = vertexCount; - } - } else { - var verticesValue = valueMap["vertices"]; - var vertices = []; - vertices.length = vertexCount; - var start = valueMap["offset"] || 0; - var nn = verticesValue.length; - if (this.scale == 1) { - for (var ii = 0; ii < nn; ii++) - vertices[ii + start] = verticesValue[ii]; - } else { - for (var ii = 0; ii < nn; ii++) - vertices[ii + start] = verticesValue[ii] * this.scale; - } - if (isMesh) { - var meshVertices = attachment.vertices; - for (var ii = 0, nn = vertices.length; ii < nn; ii++) - vertices[ii] += meshVertices[ii]; - } - } - - timeline.setFrame(frameIndex, valueMap["time"], vertices); - this.readCurve(timeline, frameIndex, valueMap); - frameIndex++; - } - timelines[timelines.length] = timeline; - duration = Math.max(duration, timeline.frames[timeline.frameCount - 1]); - } - } - } - - var drawOrderValues = map["drawOrder"]; - if (!drawOrderValues) drawOrderValues = map["draworder"]; - if (drawOrderValues) { - var timeline = new spine.DrawOrderTimeline(drawOrderValues.length); - var slotCount = skeletonData.slots.length; - var frameIndex = 0; - for (var i = 0, n = drawOrderValues.length; i < n; i++) { - var drawOrderMap = drawOrderValues[i]; - var drawOrder = null; - if (drawOrderMap["offsets"]) { - drawOrder = []; - drawOrder.length = slotCount; - for (var ii = slotCount - 1; ii >= 0; ii--) - drawOrder[ii] = -1; - var offsets = drawOrderMap["offsets"]; - var unchanged = []; - unchanged.length = slotCount - offsets.length; - var originalIndex = 0, unchangedIndex = 0; - for (var ii = 0, nn = offsets.length; ii < nn; ii++) { - var offsetMap = offsets[ii]; - var slotIndex = skeletonData.findSlotIndex(offsetMap["slot"]); - if (slotIndex == -1) throw new Error("Slot not found: " + offsetMap["slot"]); - // Collect unchanged items. - while (originalIndex != slotIndex) - unchanged[unchangedIndex++] = originalIndex++; - // Set changed items. - drawOrder[originalIndex + offsetMap["offset"]] = originalIndex++; - } - // Collect remaining unchanged items. - while (originalIndex < slotCount) - unchanged[unchangedIndex++] = originalIndex++; - // Fill in unchanged items. - for (var ii = slotCount - 1; ii >= 0; ii--) - if (drawOrder[ii] == -1) drawOrder[ii] = unchanged[--unchangedIndex]; - } - timeline.setFrame(frameIndex++, drawOrderMap["time"], drawOrder); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); - } - - var events = map["events"]; - if (events) { - var timeline = new spine.EventTimeline(events.length); - var frameIndex = 0; - for (var i = 0, n = events.length; i < n; i++) { - var eventMap = events[i]; - var eventData = skeletonData.findEvent(eventMap["name"]); - if (!eventData) throw new Error("Event not found: " + eventMap["name"]); - var event = new spine.Event(eventData); - event.intValue = eventMap.hasOwnProperty("int") ? eventMap["int"] : eventData.intValue; - event.floatValue = eventMap.hasOwnProperty("float") ? eventMap["float"] : eventData.floatValue; - event.stringValue = eventMap.hasOwnProperty("string") ? eventMap["string"] : eventData.stringValue; - timeline.setFrame(frameIndex++, eventMap["time"], event); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); - } - - skeletonData.animations.push(new spine.Animation(name, timelines, duration)); - }, - readCurve: function (timeline, frameIndex, valueMap) { - var curve = valueMap["curve"]; - if (!curve) - timeline.curves.setLinear(frameIndex); - else if (curve == "stepped") - timeline.curves.setStepped(frameIndex); - else if (curve instanceof Array) - timeline.curves.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]); - }, - toColor: function (hexString, colorIndex) { - if (hexString.length != 8) throw new Error("Color hexidecimal length must be 8, recieved: " + hexString); - return parseInt(hexString.substring(colorIndex * 2, (colorIndex * 2) + 2), 16) / 255; - }, - getFloatArray: function (map, name, scale) { - var list = map[name]; - var values = new spine.Float32Array(list.length); - var i = 0, n = list.length; - if (scale == 1) { - for (; i < n; i++) - values[i] = list[i]; - } else { - for (; i < n; i++) - values[i] = list[i] * scale; - } - return values; - }, - getIntArray: function (map, name) { - var list = map[name]; - var values = new spine.Uint16Array(list.length); - for (var i = 0, n = list.length; i < n; i++) - values[i] = list[i] | 0; - return values; - } -}; - -spine.Atlas = function (atlasText, textureLoader) { - this.textureLoader = textureLoader; - this.pages = []; - this.regions = []; - - var reader = new spine.AtlasReader(atlasText); - var tuple = []; - tuple.length = 4; - var page = null; - while (true) { - var line = reader.readLine(); - if (line === null) break; - line = reader.trim(line); - if (!line.length) - page = null; - else if (!page) { - page = new spine.AtlasPage(); - page.name = line; - - if (reader.readTuple(tuple) == 2) { // size is only optional for an atlas packed with an old TexturePacker. - page.width = parseInt(tuple[0]); - page.height = parseInt(tuple[1]); - reader.readTuple(tuple); - } - page.format = spine.Atlas.Format[tuple[0]]; - - reader.readTuple(tuple); - page.minFilter = spine.Atlas.TextureFilter[tuple[0]]; - page.magFilter = spine.Atlas.TextureFilter[tuple[1]]; - - var direction = reader.readValue(); - page.uWrap = spine.Atlas.TextureWrap.clampToEdge; - page.vWrap = spine.Atlas.TextureWrap.clampToEdge; - if (direction == "x") - page.uWrap = spine.Atlas.TextureWrap.repeat; - else if (direction == "y") - page.vWrap = spine.Atlas.TextureWrap.repeat; - else if (direction == "xy") - page.uWrap = page.vWrap = spine.Atlas.TextureWrap.repeat; - - textureLoader.load(page, line, this); - - this.pages.push(page); - - } else { - var region = new spine.AtlasRegion(); - region.name = line; - region.page = page; - - region.rotate = reader.readValue() == "true"; - - reader.readTuple(tuple); - var x = parseInt(tuple[0]); - var y = parseInt(tuple[1]); - - reader.readTuple(tuple); - var width = parseInt(tuple[0]); - var height = parseInt(tuple[1]); - - region.u = x / page.width; - region.v = y / page.height; - if (region.rotate) { - region.u2 = (x + height) / page.width; - region.v2 = (y + width) / page.height; - } else { - region.u2 = (x + width) / page.width; - region.v2 = (y + height) / page.height; - } - region.x = x; - region.y = y; - region.width = Math.abs(width); - region.height = Math.abs(height); - - if (reader.readTuple(tuple) == 4) { // split is optional - region.splits = [parseInt(tuple[0]), parseInt(tuple[1]), parseInt(tuple[2]), parseInt(tuple[3])]; - - if (reader.readTuple(tuple) == 4) { // pad is optional, but only present with splits - region.pads = [parseInt(tuple[0]), parseInt(tuple[1]), parseInt(tuple[2]), parseInt(tuple[3])]; - - reader.readTuple(tuple); - } - } - - region.originalWidth = parseInt(tuple[0]); - region.originalHeight = parseInt(tuple[1]); - - reader.readTuple(tuple); - region.offsetX = parseInt(tuple[0]); - region.offsetY = parseInt(tuple[1]); - - region.index = parseInt(reader.readValue()); - - this.regions.push(region); - } - } -}; -spine.Atlas.prototype = { - findRegion: function (name) { - var regions = this.regions; - for (var i = 0, n = regions.length; i < n; i++) - if (regions[i].name == name) return regions[i]; - return null; - }, - dispose: function () { - var pages = this.pages; - for (var i = 0, n = pages.length; i < n; i++) - this.textureLoader.unload(pages[i].rendererObject); - }, - updateUVs: function (page) { - var regions = this.regions; - for (var i = 0, n = regions.length; i < n; i++) { - var region = regions[i]; - if (region.page != page) continue; - region.u = region.x / page.width; - region.v = region.y / page.height; - if (region.rotate) { - region.u2 = (region.x + region.height) / page.width; - region.v2 = (region.y + region.width) / page.height; - } else { - region.u2 = (region.x + region.width) / page.width; - region.v2 = (region.y + region.height) / page.height; - } - } - } -}; - -spine.Atlas.Format = { - alpha: 0, - intensity: 1, - luminanceAlpha: 2, - rgb565: 3, - rgba4444: 4, - rgb888: 5, - rgba8888: 6 -}; - -spine.Atlas.TextureFilter = { - nearest: 0, - linear: 1, - mipMap: 2, - mipMapNearestNearest: 3, - mipMapLinearNearest: 4, - mipMapNearestLinear: 5, - mipMapLinearLinear: 6 -}; - -spine.Atlas.TextureWrap = { - mirroredRepeat: 0, - clampToEdge: 1, - repeat: 2 -}; - -spine.AtlasPage = function () { - this.width = this.height = 0; -}; -spine.AtlasPage.prototype = { - name: null, - format: null, - minFilter: null, - magFilter: null, - uWrap: null, - vWrap: null, - rendererObject: null, - width: 0, - height: 0 -}; - -spine.AtlasRegion = function () { - this.x = this.y = this.width = this.height = - this.u = this.v = this.u2 = this.v2 = - this.offsetX = this.offsetY = - this.originalWidth = this.originalHeight = 0; - this.index = 0; -}; -spine.AtlasRegion.prototype = { - page: null, - name: null, - x: 0, y: 0, - width: 0, height: 0, - u: 0, v: 0, u2: 0, v2: 0, - offsetX: 0, offsetY: 0, - originalWidth: 0, originalHeight: 0, - index: 0, - rotate: false, - splits: null, - pads: null -}; - -spine.AtlasReader = function (text) { - this.index = 0; - - this.lines = text.split(/\r\n|\r|\n/); -}; -spine.AtlasReader.prototype = { - index: 0, - trim: function (value) { - return value.replace(/^\s+|\s+$/g, ""); - }, - readLine: function () { - if (this.index >= this.lines.length) return null; - return this.lines[this.index++]; - }, - readValue: function () { - var line = this.readLine(); - var colon = line.indexOf(":"); - if (colon == -1) throw new Error("Invalid line: " + line); - return this.trim(line.substring(colon + 1)); - }, - /** Returns the number of tuple values read (1, 2 or 4). */ - readTuple: function (tuple) { - var line = this.readLine(); - var colon = line.indexOf(":"); - if (colon == -1) throw new Error("Invalid line: " + line); - var i = 0, lastMatch = colon + 1; - for (; i < 3; i++) { - var comma = line.indexOf(",", lastMatch); - if (comma == -1) break; - tuple[i] = this.trim(line.substr(lastMatch, comma - lastMatch)); - lastMatch = comma + 1; - } - tuple[i] = this.trim(line.substring(lastMatch)); - return i + 1; - } -}; - -spine.AtlasAttachmentLoader = function (atlas) { - this.atlas = atlas; -}; -spine.AtlasAttachmentLoader.prototype = { - newRegionAttachment: function (skin, name, path) { - var region = this.atlas.findRegion(path); - if (!region) throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")"); - var attachment = new spine.RegionAttachment(name); - attachment.rendererObject = region; - attachment.setUVs(region.u, region.v, region.u2, region.v2, region.rotate); - attachment.regionOffsetX = region.offsetX; - attachment.regionOffsetY = region.offsetY; - attachment.regionWidth = region.width; - attachment.regionHeight = region.height; - attachment.regionOriginalWidth = region.originalWidth; - attachment.regionOriginalHeight = region.originalHeight; - return attachment; - }, - newMeshAttachment: function (skin, name, path) { - var region = this.atlas.findRegion(path); - if (!region) throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")"); - var attachment = new spine.MeshAttachment(name); - attachment.rendererObject = region; - attachment.regionU = region.u; - attachment.regionV = region.v; - attachment.regionU2 = region.u2; - attachment.regionV2 = region.v2; - attachment.regionRotate = region.rotate; - attachment.regionOffsetX = region.offsetX; - attachment.regionOffsetY = region.offsetY; - attachment.regionWidth = region.width; - attachment.regionHeight = region.height; - attachment.regionOriginalWidth = region.originalWidth; - attachment.regionOriginalHeight = region.originalHeight; - return attachment; - }, - newSkinnedMeshAttachment: function (skin, name, path) { - var region = this.atlas.findRegion(path); - if (!region) throw new Error("Region not found in atlas: " + path + " (skinned mesh attachment: " + name + ")"); - var attachment = new spine.SkinnedMeshAttachment(name); - attachment.rendererObject = region; - attachment.regionU = region.u; - attachment.regionV = region.v; - attachment.regionU2 = region.u2; - attachment.regionV2 = region.v2; - attachment.regionRotate = region.rotate; - attachment.regionOffsetX = region.offsetX; - attachment.regionOffsetY = region.offsetY; - attachment.regionWidth = region.width; - attachment.regionHeight = region.height; - attachment.regionOriginalWidth = region.originalWidth; - attachment.regionOriginalHeight = region.originalHeight; - return attachment; - }, - newBoundingBoxAttachment: function (skin, name) { - return new spine.BoundingBoxAttachment(name); - } -}; - -spine.SkeletonBounds = function () { - this.minX = this.minY = this.maxX = this.maxY = 0; - - this.polygonPool = []; - this.polygons = []; - this.boundingBoxes = []; -}; -spine.SkeletonBounds.prototype = { - minX: 0, minY: 0, maxX: 0, maxY: 0, - update: function (skeleton, updateAabb) { - var slots = skeleton.slots; - var slotCount = slots.length; - var x = skeleton.x, y = skeleton.y; - var boundingBoxes = this.boundingBoxes; - var polygonPool = this.polygonPool; - var polygons = this.polygons; - - boundingBoxes.length = 0; - for (var i = 0, n = polygons.length; i < n; i++) - polygonPool.push(polygons[i]); - polygons.length = 0; - - for (var i = 0; i < slotCount; i++) { - var slot = slots[i]; - var boundingBox = slot.attachment; - if (boundingBox.type != spine.AttachmentType.boundingbox) continue; - boundingBoxes.push(boundingBox); - - var poolCount = polygonPool.length, polygon; - if (poolCount > 0) { - polygon = polygonPool[poolCount - 1]; - polygonPool.splice(poolCount - 1, 1); - } else - polygon = []; - polygons.push(polygon); - - polygon.length = boundingBox.vertices.length; - boundingBox.computeWorldVertices(x, y, slot.bone, polygon); - } - - if (updateAabb) this.aabbCompute(); - }, - aabbCompute: function () { - var polygons = this.polygons; - var minX = Number.MAX_VALUE, minY = Number.MAX_VALUE, maxX = Number.MIN_VALUE, maxY = Number.MIN_VALUE; - for (var i = 0, n = polygons.length; i < n; i++) { - var vertices = polygons[i]; - for (var ii = 0, nn = vertices.length; ii < nn; ii += 2) { - var x = vertices[ii]; - var y = vertices[ii + 1]; - minX = Math.min(minX, x); - minY = Math.min(minY, y); - maxX = Math.max(maxX, x); - maxY = Math.max(maxY, y); - } - } - this.minX = minX; - this.minY = minY; - this.maxX = maxX; - this.maxY = maxY; - }, - /** Returns true if the axis aligned bounding box contains the point. */ - aabbContainsPoint: function (x, y) { - return x >= this.minX && x <= this.maxX && y >= this.minY && y <= this.maxY; - }, - /** Returns true if the axis aligned bounding box intersects the line segment. */ - aabbIntersectsSegment: function (x1, y1, x2, y2) { - var minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY; - if ((x1 <= minX && x2 <= minX) || (y1 <= minY && y2 <= minY) || (x1 >= maxX && x2 >= maxX) || (y1 >= maxY && y2 >= maxY)) - return false; - var m = (y2 - y1) / (x2 - x1); - var y = m * (minX - x1) + y1; - if (y > minY && y < maxY) return true; - y = m * (maxX - x1) + y1; - if (y > minY && y < maxY) return true; - var x = (minY - y1) / m + x1; - if (x > minX && x < maxX) return true; - x = (maxY - y1) / m + x1; - if (x > minX && x < maxX) return true; - return false; - }, - /** Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. */ - aabbIntersectsSkeleton: function (bounds) { - return this.minX < bounds.maxX && this.maxX > bounds.minX && this.minY < bounds.maxY && this.maxY > bounds.minY; - }, - /** Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more - * efficient to only call this method if {@link #aabbContainsPoint(float, float)} returns true. */ - containsPoint: function (x, y) { - var polygons = this.polygons; - for (var i = 0, n = polygons.length; i < n; i++) - if (this.polygonContainsPoint(polygons[i], x, y)) return this.boundingBoxes[i]; - return null; - }, - /** Returns the first bounding box attachment that contains the line segment, or null. When doing many checks, it is usually - * more efficient to only call this method if {@link #aabbIntersectsSegment(float, float, float, float)} returns true. */ - intersectsSegment: function (x1, y1, x2, y2) { - var polygons = this.polygons; - for (var i = 0, n = polygons.length; i < n; i++) - if (polygons[i].intersectsSegment(x1, y1, x2, y2)) return this.boundingBoxes[i]; - return null; - }, - /** Returns true if the polygon contains the point. */ - polygonContainsPoint: function (polygon, x, y) { - var nn = polygon.length; - var prevIndex = nn - 2; - var inside = false; - for (var ii = 0; ii < nn; ii += 2) { - var vertexY = polygon[ii + 1]; - var prevY = polygon[prevIndex + 1]; - if ((vertexY < y && prevY >= y) || (prevY < y && vertexY >= y)) { - var vertexX = polygon[ii]; - if (vertexX + (y - vertexY) / (prevY - vertexY) * (polygon[prevIndex] - vertexX) < x) inside = !inside; - } - prevIndex = ii; - } - return inside; - }, - /** Returns true if the polygon contains the line segment. */ - polygonIntersectsSegment: function (polygon, x1, y1, x2, y2) { - var nn = polygon.length; - var width12 = x1 - x2, height12 = y1 - y2; - var det1 = x1 * y2 - y1 * x2; - var x3 = polygon[nn - 2], y3 = polygon[nn - 1]; - for (var ii = 0; ii < nn; ii += 2) { - var x4 = polygon[ii], y4 = polygon[ii + 1]; - var det2 = x3 * y4 - y3 * x4; - var width34 = x3 - x4, height34 = y3 - y4; - var det3 = width12 * height34 - height12 * width34; - var x = (det1 * width34 - width12 * det2) / det3; - if (((x >= x3 && x <= x4) || (x >= x4 && x <= x3)) && ((x >= x1 && x <= x2) || (x >= x2 && x <= x1))) { - var y = (det1 * height34 - height12 * det2) / det3; - if (((y >= y3 && y <= y4) || (y >= y4 && y <= y3)) && ((y >= y1 && y <= y2) || (y >= y2 && y <= y1))) return true; - } - x3 = x4; - y3 = y4; - } - return false; - }, - getPolygon: function (attachment) { - var index = this.boundingBoxes.indexOf(attachment); - return index == -1 ? null : this.polygons[index]; - }, - getWidth: function () { - return this.maxX - this.minX; - }, - getHeight: function () { - return this.maxY - this.minY; - } -}; diff --git a/external/box2d/box2d.js b/external/box2d/box2d.js index 55fc3b047e..e69de29bb2 100644 --- a/external/box2d/box2d.js +++ b/external/box2d/box2d.js @@ -1,10882 +0,0 @@ -/* - * Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * - * Sean Lin 2012-5-8, - * - * The library is box2dweb, http://code.google.com/p/box2dweb/ - * - * It is a port of Box2DFlash 2.1a to JavaScript. - * You can read the documentation for Box2dFlash, since nearly everything is - * organized the same way. http://www.box2dflash.org/docs/2.1a/reference/ - * - */ - -var Box2D = {}; - -(function (a2j, undefined) { - - if(!(Object.defineProperty instanceof Function) - && Object.prototype.__defineGetter__ instanceof Function - && Object.prototype.__defineSetter__ instanceof Function) - { - Object.defineProperty = function(obj, p, cfg) { - if(cfg.get instanceof Function) - obj.__defineGetter__(p, cfg.get); - if(cfg.set instanceof Function) - obj.__defineSetter__(p, cfg.set); - } - } - - function emptyFn() {}; - a2j.inherit = function(cls, base) { - var tmpCtr = cls; - emptyFn.prototype = base.prototype; - cls.prototype = new emptyFn; - cls.prototype.constructor = tmpCtr; - }; - - a2j.generateCallback = function generateCallback(context, cb) { - return function () { - cb.apply(context, arguments); - }; - }; - - a2j.NVector = function NVector(length) { - if (length === undefined) length = 0; - var tmp = new Array(length || 0); - for (var i = 0; i < length; ++i) - tmp[i] = 0; - return tmp; - }; - - a2j.is = function is(o1, o2) { - if (o1 === null) return false; - if ((o2 instanceof Function) && (o1 instanceof o2)) return true; - if ((o1.constructor.__implements != undefined) && (o1.constructor.__implements[o2])) return true; - return false; - }; - - a2j.parseUInt = function(v) { - return Math.abs(parseInt(v)); - } - -})(Box2D); - -//#TODO remove assignments from global namespace -var Vector = Array; -var Vector_a2j_Number = Box2D.NVector; -//package structure -if (typeof(Box2D) === "undefined") Box2D = {}; -if (typeof(Box2D.Collision) === "undefined") Box2D.Collision = {}; -if (typeof(Box2D.Collision.Shapes) === "undefined") Box2D.Collision.Shapes = {}; -if (typeof(Box2D.Common) === "undefined") Box2D.Common = {}; -if (typeof(Box2D.Common.Math) === "undefined") Box2D.Common.Math = {}; -if (typeof(Box2D.Dynamics) === "undefined") Box2D.Dynamics = {}; -if (typeof(Box2D.Dynamics.Contacts) === "undefined") Box2D.Dynamics.Contacts = {}; -if (typeof(Box2D.Dynamics.Controllers) === "undefined") Box2D.Dynamics.Controllers = {}; -if (typeof(Box2D.Dynamics.Joints) === "undefined") Box2D.Dynamics.Joints = {}; -//pre-definitions -(function () { - Box2D.Collision.IBroadPhase = 'Box2D.Collision.IBroadPhase'; - - function b2AABB() { - b2AABB.b2AABB.apply(this, arguments); - }; - Box2D.Collision.b2AABB = b2AABB; - - function b2Bound() { - b2Bound.b2Bound.apply(this, arguments); - }; - Box2D.Collision.b2Bound = b2Bound; - - function b2BoundValues() { - b2BoundValues.b2BoundValues.apply(this, arguments); - if (this.constructor === b2BoundValues) this.b2BoundValues.apply(this, arguments); - }; - Box2D.Collision.b2BoundValues = b2BoundValues; - - function b2Collision() { - b2Collision.b2Collision.apply(this, arguments); - }; - Box2D.Collision.b2Collision = b2Collision; - - function b2ContactID() { - b2ContactID.b2ContactID.apply(this, arguments); - if (this.constructor === b2ContactID) this.b2ContactID.apply(this, arguments); - }; - Box2D.Collision.b2ContactID = b2ContactID; - - function b2ContactPoint() { - b2ContactPoint.b2ContactPoint.apply(this, arguments); - }; - Box2D.Collision.b2ContactPoint = b2ContactPoint; - - function b2Distance() { - b2Distance.b2Distance.apply(this, arguments); - }; - Box2D.Collision.b2Distance = b2Distance; - - function b2DistanceInput() { - b2DistanceInput.b2DistanceInput.apply(this, arguments); - }; - Box2D.Collision.b2DistanceInput = b2DistanceInput; - - function b2DistanceOutput() { - b2DistanceOutput.b2DistanceOutput.apply(this, arguments); - }; - Box2D.Collision.b2DistanceOutput = b2DistanceOutput; - - function b2DistanceProxy() { - b2DistanceProxy.b2DistanceProxy.apply(this, arguments); - }; - Box2D.Collision.b2DistanceProxy = b2DistanceProxy; - - function b2DynamicTree() { - b2DynamicTree.b2DynamicTree.apply(this, arguments); - if (this.constructor === b2DynamicTree) this.b2DynamicTree.apply(this, arguments); - }; - Box2D.Collision.b2DynamicTree = b2DynamicTree; - - function b2DynamicTreeBroadPhase() { - b2DynamicTreeBroadPhase.b2DynamicTreeBroadPhase.apply(this, arguments); - }; - Box2D.Collision.b2DynamicTreeBroadPhase = b2DynamicTreeBroadPhase; - - function b2DynamicTreeNode() { - b2DynamicTreeNode.b2DynamicTreeNode.apply(this, arguments); - }; - Box2D.Collision.b2DynamicTreeNode = b2DynamicTreeNode; - - function b2DynamicTreePair() { - b2DynamicTreePair.b2DynamicTreePair.apply(this, arguments); - }; - Box2D.Collision.b2DynamicTreePair = b2DynamicTreePair; - - function b2Manifold() { - b2Manifold.b2Manifold.apply(this, arguments); - if (this.constructor === b2Manifold) this.b2Manifold.apply(this, arguments); - }; - Box2D.Collision.b2Manifold = b2Manifold; - - function b2ManifoldPoint() { - b2ManifoldPoint.b2ManifoldPoint.apply(this, arguments); - if (this.constructor === b2ManifoldPoint) this.b2ManifoldPoint.apply(this, arguments); - }; - Box2D.Collision.b2ManifoldPoint = b2ManifoldPoint; - - function b2Point() { - b2Point.b2Point.apply(this, arguments); - }; - Box2D.Collision.b2Point = b2Point; - - function b2RayCastInput() { - b2RayCastInput.b2RayCastInput.apply(this, arguments); - if (this.constructor === b2RayCastInput) this.b2RayCastInput.apply(this, arguments); - }; - Box2D.Collision.b2RayCastInput = b2RayCastInput; - - function b2RayCastOutput() { - b2RayCastOutput.b2RayCastOutput.apply(this, arguments); - }; - Box2D.Collision.b2RayCastOutput = b2RayCastOutput; - - function b2Segment() { - b2Segment.b2Segment.apply(this, arguments); - }; - Box2D.Collision.b2Segment = b2Segment; - - function b2SeparationFunction() { - b2SeparationFunction.b2SeparationFunction.apply(this, arguments); - }; - Box2D.Collision.b2SeparationFunction = b2SeparationFunction; - - function b2Simplex() { - b2Simplex.b2Simplex.apply(this, arguments); - if (this.constructor === b2Simplex) this.b2Simplex.apply(this, arguments); - }; - Box2D.Collision.b2Simplex = b2Simplex; - - function b2SimplexCache() { - b2SimplexCache.b2SimplexCache.apply(this, arguments); - }; - Box2D.Collision.b2SimplexCache = b2SimplexCache; - - function b2SimplexVertex() { - b2SimplexVertex.b2SimplexVertex.apply(this, arguments); - }; - Box2D.Collision.b2SimplexVertex = b2SimplexVertex; - - function b2TimeOfImpact() { - b2TimeOfImpact.b2TimeOfImpact.apply(this, arguments); - }; - Box2D.Collision.b2TimeOfImpact = b2TimeOfImpact; - - function b2TOIInput() { - b2TOIInput.b2TOIInput.apply(this, arguments); - }; - Box2D.Collision.b2TOIInput = b2TOIInput; - - function b2WorldManifold() { - b2WorldManifold.b2WorldManifold.apply(this, arguments); - if (this.constructor === b2WorldManifold) this.b2WorldManifold.apply(this, arguments); - }; - Box2D.Collision.b2WorldManifold = b2WorldManifold; - - function ClipVertex() { - ClipVertex.ClipVertex.apply(this, arguments); - }; - Box2D.Collision.ClipVertex = ClipVertex; - - function Features() { - Features.Features.apply(this, arguments); - }; - Box2D.Collision.Features = Features; - - function b2CircleShape() { - b2CircleShape.b2CircleShape.apply(this, arguments); - if (this.constructor === b2CircleShape) this.b2CircleShape.apply(this, arguments); - }; - Box2D.Collision.Shapes.b2CircleShape = b2CircleShape; - - function b2EdgeChainDef() { - b2EdgeChainDef.b2EdgeChainDef.apply(this, arguments); - if (this.constructor === b2EdgeChainDef) this.b2EdgeChainDef.apply(this, arguments); - }; - Box2D.Collision.Shapes.b2EdgeChainDef = b2EdgeChainDef; - - function b2EdgeShape() { - b2EdgeShape.b2EdgeShape.apply(this, arguments); - if (this.constructor === b2EdgeShape) this.b2EdgeShape.apply(this, arguments); - }; - Box2D.Collision.Shapes.b2EdgeShape = b2EdgeShape; - - function b2MassData() { - b2MassData.b2MassData.apply(this, arguments); - }; - Box2D.Collision.Shapes.b2MassData = b2MassData; - - function b2PolygonShape() { - b2PolygonShape.b2PolygonShape.apply(this, arguments); - if (this.constructor === b2PolygonShape) this.b2PolygonShape.apply(this, arguments); - }; - Box2D.Collision.Shapes.b2PolygonShape = b2PolygonShape; - - function b2Shape() { - b2Shape.b2Shape.apply(this, arguments); - if (this.constructor === b2Shape) this.b2Shape.apply(this, arguments); - }; - Box2D.Collision.Shapes.b2Shape = b2Shape; - Box2D.Common.b2internal = 'Box2D.Common.b2internal'; - - function b2Color() { - b2Color.b2Color.apply(this, arguments); - if (this.constructor === b2Color) this.b2Color.apply(this, arguments); - }; - Box2D.Common.b2Color = b2Color; - - function b2Settings() { - b2Settings.b2Settings.apply(this, arguments); - }; - Box2D.Common.b2Settings = b2Settings; - - function b2Mat22() { - b2Mat22.b2Mat22.apply(this, arguments); - if (this.constructor === b2Mat22) this.b2Mat22.apply(this, arguments); - }; - Box2D.Common.Math.b2Mat22 = b2Mat22; - - function b2Mat33() { - b2Mat33.b2Mat33.apply(this, arguments); - if (this.constructor === b2Mat33) this.b2Mat33.apply(this, arguments); - }; - Box2D.Common.Math.b2Mat33 = b2Mat33; - - function b2Math() { - b2Math.b2Math.apply(this, arguments); - }; - Box2D.Common.Math.b2Math = b2Math; - - function b2Sweep() { - b2Sweep.b2Sweep.apply(this, arguments); - }; - Box2D.Common.Math.b2Sweep = b2Sweep; - - function b2Transform() { - b2Transform.b2Transform.apply(this, arguments); - if (this.constructor === b2Transform) this.b2Transform.apply(this, arguments); - }; - Box2D.Common.Math.b2Transform = b2Transform; - - function b2Vec2() { - b2Vec2.b2Vec2.apply(this, arguments); - if (this.constructor === b2Vec2) this.b2Vec2.apply(this, arguments); - }; - Box2D.Common.Math.b2Vec2 = b2Vec2; - - function b2Vec3() { - b2Vec3.b2Vec3.apply(this, arguments); - if (this.constructor === b2Vec3) this.b2Vec3.apply(this, arguments); - }; - Box2D.Common.Math.b2Vec3 = b2Vec3; - - function b2Body() { - b2Body.b2Body.apply(this, arguments); - if (this.constructor === b2Body) this.b2Body.apply(this, arguments); - }; - Box2D.Dynamics.b2Body = b2Body; - - function b2BodyDef() { - b2BodyDef.b2BodyDef.apply(this, arguments); - if (this.constructor === b2BodyDef) this.b2BodyDef.apply(this, arguments); - }; - Box2D.Dynamics.b2BodyDef = b2BodyDef; - - function b2ContactFilter() { - b2ContactFilter.b2ContactFilter.apply(this, arguments); - }; - Box2D.Dynamics.b2ContactFilter = b2ContactFilter; - - function b2ContactImpulse() { - b2ContactImpulse.b2ContactImpulse.apply(this, arguments); - }; - Box2D.Dynamics.b2ContactImpulse = b2ContactImpulse; - - function b2ContactListener() { - b2ContactListener.b2ContactListener.apply(this, arguments); - }; - Box2D.Dynamics.b2ContactListener = b2ContactListener; - - function b2ContactManager() { - b2ContactManager.b2ContactManager.apply(this, arguments); - if (this.constructor === b2ContactManager) this.b2ContactManager.apply(this, arguments); - }; - Box2D.Dynamics.b2ContactManager = b2ContactManager; - - function b2DebugDraw() { - b2DebugDraw.b2DebugDraw.apply(this, arguments); - if (this.constructor === b2DebugDraw) this.b2DebugDraw.apply(this, arguments); - }; - Box2D.Dynamics.b2DebugDraw = b2DebugDraw; - - function b2DestructionListener() { - b2DestructionListener.b2DestructionListener.apply(this, arguments); - }; - Box2D.Dynamics.b2DestructionListener = b2DestructionListener; - - function b2FilterData() { - b2FilterData.b2FilterData.apply(this, arguments); - }; - Box2D.Dynamics.b2FilterData = b2FilterData; - - function b2Fixture() { - b2Fixture.b2Fixture.apply(this, arguments); - if (this.constructor === b2Fixture) this.b2Fixture.apply(this, arguments); - }; - Box2D.Dynamics.b2Fixture = b2Fixture; - - function b2FixtureDef() { - b2FixtureDef.b2FixtureDef.apply(this, arguments); - if (this.constructor === b2FixtureDef) this.b2FixtureDef.apply(this, arguments); - }; - Box2D.Dynamics.b2FixtureDef = b2FixtureDef; - - function b2Island() { - b2Island.b2Island.apply(this, arguments); - if (this.constructor === b2Island) this.b2Island.apply(this, arguments); - }; - Box2D.Dynamics.b2Island = b2Island; - - function b2TimeStep() { - b2TimeStep.b2TimeStep.apply(this, arguments); - }; - Box2D.Dynamics.b2TimeStep = b2TimeStep; - - function b2World() { - b2World.b2World.apply(this, arguments); - if (this.constructor === b2World) this.b2World.apply(this, arguments); - }; - Box2D.Dynamics.b2World = b2World; - - function b2CircleContact() { - b2CircleContact.b2CircleContact.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2CircleContact = b2CircleContact; - - function b2Contact() { - b2Contact.b2Contact.apply(this, arguments); - if (this.constructor === b2Contact) this.b2Contact.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2Contact = b2Contact; - - function b2ContactConstraint() { - b2ContactConstraint.b2ContactConstraint.apply(this, arguments); - if (this.constructor === b2ContactConstraint) this.b2ContactConstraint.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2ContactConstraint = b2ContactConstraint; - - function b2ContactConstraintPoint() { - b2ContactConstraintPoint.b2ContactConstraintPoint.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2ContactConstraintPoint = b2ContactConstraintPoint; - - function b2ContactEdge() { - b2ContactEdge.b2ContactEdge.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2ContactEdge = b2ContactEdge; - - function b2ContactFactory() { - b2ContactFactory.b2ContactFactory.apply(this, arguments); - if (this.constructor === b2ContactFactory) this.b2ContactFactory.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2ContactFactory = b2ContactFactory; - - function b2ContactRegister() { - b2ContactRegister.b2ContactRegister.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2ContactRegister = b2ContactRegister; - - function b2ContactResult() { - b2ContactResult.b2ContactResult.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2ContactResult = b2ContactResult; - - function b2ContactSolver() { - b2ContactSolver.b2ContactSolver.apply(this, arguments); - if (this.constructor === b2ContactSolver) this.b2ContactSolver.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2ContactSolver = b2ContactSolver; - - function b2EdgeAndCircleContact() { - b2EdgeAndCircleContact.b2EdgeAndCircleContact.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2EdgeAndCircleContact = b2EdgeAndCircleContact; - - function b2NullContact() { - b2NullContact.b2NullContact.apply(this, arguments); - if (this.constructor === b2NullContact) this.b2NullContact.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2NullContact = b2NullContact; - - function b2PolyAndCircleContact() { - b2PolyAndCircleContact.b2PolyAndCircleContact.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2PolyAndCircleContact = b2PolyAndCircleContact; - - function b2PolyAndEdgeContact() { - b2PolyAndEdgeContact.b2PolyAndEdgeContact.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2PolyAndEdgeContact = b2PolyAndEdgeContact; - - function b2PolygonContact() { - b2PolygonContact.b2PolygonContact.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2PolygonContact = b2PolygonContact; - - function b2PositionSolverManifold() { - b2PositionSolverManifold.b2PositionSolverManifold.apply(this, arguments); - if (this.constructor === b2PositionSolverManifold) this.b2PositionSolverManifold.apply(this, arguments); - }; - Box2D.Dynamics.Contacts.b2PositionSolverManifold = b2PositionSolverManifold; - - function b2BuoyancyController() { - b2BuoyancyController.b2BuoyancyController.apply(this, arguments); - }; - Box2D.Dynamics.Controllers.b2BuoyancyController = b2BuoyancyController; - - function b2ConstantAccelController() { - b2ConstantAccelController.b2ConstantAccelController.apply(this, arguments); - }; - Box2D.Dynamics.Controllers.b2ConstantAccelController = b2ConstantAccelController; - - function b2ConstantForceController() { - b2ConstantForceController.b2ConstantForceController.apply(this, arguments); - }; - Box2D.Dynamics.Controllers.b2ConstantForceController = b2ConstantForceController; - - function b2Controller() { - b2Controller.b2Controller.apply(this, arguments); - }; - Box2D.Dynamics.Controllers.b2Controller = b2Controller; - - function b2ControllerEdge() { - b2ControllerEdge.b2ControllerEdge.apply(this, arguments); - }; - Box2D.Dynamics.Controllers.b2ControllerEdge = b2ControllerEdge; - - function b2GravityController() { - b2GravityController.b2GravityController.apply(this, arguments); - }; - Box2D.Dynamics.Controllers.b2GravityController = b2GravityController; - - function b2TensorDampingController() { - b2TensorDampingController.b2TensorDampingController.apply(this, arguments); - }; - Box2D.Dynamics.Controllers.b2TensorDampingController = b2TensorDampingController; - - function b2DistanceJoint() { - b2DistanceJoint.b2DistanceJoint.apply(this, arguments); - if (this.constructor === b2DistanceJoint) this.b2DistanceJoint.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2DistanceJoint = b2DistanceJoint; - - function b2DistanceJointDef() { - b2DistanceJointDef.b2DistanceJointDef.apply(this, arguments); - if (this.constructor === b2DistanceJointDef) this.b2DistanceJointDef.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2DistanceJointDef = b2DistanceJointDef; - - function b2FrictionJoint() { - b2FrictionJoint.b2FrictionJoint.apply(this, arguments); - if (this.constructor === b2FrictionJoint) this.b2FrictionJoint.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2FrictionJoint = b2FrictionJoint; - - function b2FrictionJointDef() { - b2FrictionJointDef.b2FrictionJointDef.apply(this, arguments); - if (this.constructor === b2FrictionJointDef) this.b2FrictionJointDef.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2FrictionJointDef = b2FrictionJointDef; - - function b2GearJoint() { - b2GearJoint.b2GearJoint.apply(this, arguments); - if (this.constructor === b2GearJoint) this.b2GearJoint.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2GearJoint = b2GearJoint; - - function b2GearJointDef() { - b2GearJointDef.b2GearJointDef.apply(this, arguments); - if (this.constructor === b2GearJointDef) this.b2GearJointDef.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2GearJointDef = b2GearJointDef; - - function b2Jacobian() { - b2Jacobian.b2Jacobian.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2Jacobian = b2Jacobian; - - function b2Joint() { - b2Joint.b2Joint.apply(this, arguments); - if (this.constructor === b2Joint) this.b2Joint.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2Joint = b2Joint; - - function b2JointDef() { - b2JointDef.b2JointDef.apply(this, arguments); - if (this.constructor === b2JointDef) this.b2JointDef.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2JointDef = b2JointDef; - - function b2JointEdge() { - b2JointEdge.b2JointEdge.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2JointEdge = b2JointEdge; - - function b2LineJoint() { - b2LineJoint.b2LineJoint.apply(this, arguments); - if (this.constructor === b2LineJoint) this.b2LineJoint.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2LineJoint = b2LineJoint; - - function b2LineJointDef() { - b2LineJointDef.b2LineJointDef.apply(this, arguments); - if (this.constructor === b2LineJointDef) this.b2LineJointDef.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2LineJointDef = b2LineJointDef; - - function b2MouseJoint() { - b2MouseJoint.b2MouseJoint.apply(this, arguments); - if (this.constructor === b2MouseJoint) this.b2MouseJoint.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2MouseJoint = b2MouseJoint; - - function b2MouseJointDef() { - b2MouseJointDef.b2MouseJointDef.apply(this, arguments); - if (this.constructor === b2MouseJointDef) this.b2MouseJointDef.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2MouseJointDef = b2MouseJointDef; - - function b2PrismaticJoint() { - b2PrismaticJoint.b2PrismaticJoint.apply(this, arguments); - if (this.constructor === b2PrismaticJoint) this.b2PrismaticJoint.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2PrismaticJoint = b2PrismaticJoint; - - function b2PrismaticJointDef() { - b2PrismaticJointDef.b2PrismaticJointDef.apply(this, arguments); - if (this.constructor === b2PrismaticJointDef) this.b2PrismaticJointDef.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2PrismaticJointDef = b2PrismaticJointDef; - - function b2PulleyJoint() { - b2PulleyJoint.b2PulleyJoint.apply(this, arguments); - if (this.constructor === b2PulleyJoint) this.b2PulleyJoint.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2PulleyJoint = b2PulleyJoint; - - function b2PulleyJointDef() { - b2PulleyJointDef.b2PulleyJointDef.apply(this, arguments); - if (this.constructor === b2PulleyJointDef) this.b2PulleyJointDef.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2PulleyJointDef = b2PulleyJointDef; - - function b2RevoluteJoint() { - b2RevoluteJoint.b2RevoluteJoint.apply(this, arguments); - if (this.constructor === b2RevoluteJoint) this.b2RevoluteJoint.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2RevoluteJoint = b2RevoluteJoint; - - function b2RevoluteJointDef() { - b2RevoluteJointDef.b2RevoluteJointDef.apply(this, arguments); - if (this.constructor === b2RevoluteJointDef) this.b2RevoluteJointDef.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2RevoluteJointDef = b2RevoluteJointDef; - - function b2WeldJoint() { - b2WeldJoint.b2WeldJoint.apply(this, arguments); - if (this.constructor === b2WeldJoint) this.b2WeldJoint.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2WeldJoint = b2WeldJoint; - - function b2WeldJointDef() { - b2WeldJointDef.b2WeldJointDef.apply(this, arguments); - if (this.constructor === b2WeldJointDef) this.b2WeldJointDef.apply(this, arguments); - }; - Box2D.Dynamics.Joints.b2WeldJointDef = b2WeldJointDef; -})(); //definitions -Box2D.postDefs = []; -(function () { - var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape, - b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef, - b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape, - b2MassData = Box2D.Collision.Shapes.b2MassData, - b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape, - b2Shape = Box2D.Collision.Shapes.b2Shape, - b2Color = Box2D.Common.b2Color, - b2internal = Box2D.Common.b2internal, - b2Settings = Box2D.Common.b2Settings, - b2Mat22 = Box2D.Common.Math.b2Mat22, - b2Mat33 = Box2D.Common.Math.b2Mat33, - b2Math = Box2D.Common.Math.b2Math, - b2Sweep = Box2D.Common.Math.b2Sweep, - b2Transform = Box2D.Common.Math.b2Transform, - b2Vec2 = Box2D.Common.Math.b2Vec2, - b2Vec3 = Box2D.Common.Math.b2Vec3, - b2AABB = Box2D.Collision.b2AABB, - b2Bound = Box2D.Collision.b2Bound, - b2BoundValues = Box2D.Collision.b2BoundValues, - b2Collision = Box2D.Collision.b2Collision, - b2ContactID = Box2D.Collision.b2ContactID, - b2ContactPoint = Box2D.Collision.b2ContactPoint, - b2Distance = Box2D.Collision.b2Distance, - b2DistanceInput = Box2D.Collision.b2DistanceInput, - b2DistanceOutput = Box2D.Collision.b2DistanceOutput, - b2DistanceProxy = Box2D.Collision.b2DistanceProxy, - b2DynamicTree = Box2D.Collision.b2DynamicTree, - b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase, - b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode, - b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair, - b2Manifold = Box2D.Collision.b2Manifold, - b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint, - b2Point = Box2D.Collision.b2Point, - b2RayCastInput = Box2D.Collision.b2RayCastInput, - b2RayCastOutput = Box2D.Collision.b2RayCastOutput, - b2Segment = Box2D.Collision.b2Segment, - b2SeparationFunction = Box2D.Collision.b2SeparationFunction, - b2Simplex = Box2D.Collision.b2Simplex, - b2SimplexCache = Box2D.Collision.b2SimplexCache, - b2SimplexVertex = Box2D.Collision.b2SimplexVertex, - b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact, - b2TOIInput = Box2D.Collision.b2TOIInput, - b2WorldManifold = Box2D.Collision.b2WorldManifold, - ClipVertex = Box2D.Collision.ClipVertex, - Features = Box2D.Collision.Features, - IBroadPhase = Box2D.Collision.IBroadPhase; - - b2AABB.b2AABB = function () { - this.lowerBound = new b2Vec2(); - this.upperBound = new b2Vec2(); - }; - b2AABB.prototype.IsValid = function () { - var dX = this.upperBound.x - this.lowerBound.x; - var dY = this.upperBound.y - this.lowerBound.y; - var valid = dX >= 0.0 && dY >= 0.0; - valid = valid && this.lowerBound.IsValid() && this.upperBound.IsValid(); - return valid; - } - b2AABB.prototype.GetCenter = function () { - return new b2Vec2((this.lowerBound.x + this.upperBound.x) / 2, (this.lowerBound.y + this.upperBound.y) / 2); - } - b2AABB.prototype.GetExtents = function () { - return new b2Vec2((this.upperBound.x - this.lowerBound.x) / 2, (this.upperBound.y - this.lowerBound.y) / 2); - } - b2AABB.prototype.Contains = function (aabb) { - var result = true; - result = result && this.lowerBound.x <= aabb.lowerBound.x; - result = result && this.lowerBound.y <= aabb.lowerBound.y; - result = result && aabb.upperBound.x <= this.upperBound.x; - result = result && aabb.upperBound.y <= this.upperBound.y; - return result; - } - b2AABB.prototype.RayCast = function (output, input) { - var tmin = (-Number.MAX_VALUE); - var tmax = Number.MAX_VALUE; - var pX = input.p1.x; - var pY = input.p1.y; - var dX = input.p2.x - input.p1.x; - var dY = input.p2.y - input.p1.y; - var absDX = Math.abs(dX); - var absDY = Math.abs(dY); - var normal = output.normal; - var inv_d = 0; - var t1 = 0; - var t2 = 0; - var t3 = 0; - var s = 0; { - if (absDX < Number.MIN_VALUE) { - if (pX < this.lowerBound.x || this.upperBound.x < pX) return false; - } - else { - inv_d = 1.0 / dX; - t1 = (this.lowerBound.x - pX) * inv_d; - t2 = (this.upperBound.x - pX) * inv_d; - s = (-1.0); - if (t1 > t2) { - t3 = t1; - t1 = t2; - t2 = t3; - s = 1.0; - } - if (t1 > tmin) { - normal.x = s; - normal.y = 0; - tmin = t1; - } - tmax = Math.min(tmax, t2); - if (tmin > tmax) return false; - } - } { - if (absDY < Number.MIN_VALUE) { - if (pY < this.lowerBound.y || this.upperBound.y < pY) return false; - } - else { - inv_d = 1.0 / dY; - t1 = (this.lowerBound.y - pY) * inv_d; - t2 = (this.upperBound.y - pY) * inv_d; - s = (-1.0); - if (t1 > t2) { - t3 = t1; - t1 = t2; - t2 = t3; - s = 1.0; - } - if (t1 > tmin) { - normal.y = s; - normal.x = 0; - tmin = t1; - } - tmax = Math.min(tmax, t2); - if (tmin > tmax) return false; - } - } - output.fraction = tmin; - return true; - } - b2AABB.prototype.TestOverlap = function (other) { - var d1X = other.lowerBound.x - this.upperBound.x; - var d1Y = other.lowerBound.y - this.upperBound.y; - var d2X = this.lowerBound.x - other.upperBound.x; - var d2Y = this.lowerBound.y - other.upperBound.y; - if (d1X > 0.0 || d1Y > 0.0) return false; - if (d2X > 0.0 || d2Y > 0.0) return false; - return true; - } - b2AABB.Combine = function (aabb1, aabb2) { - var aabb = new b2AABB(); - aabb.Combine(aabb1, aabb2); - return aabb; - } - b2AABB.prototype.Combine = function (aabb1, aabb2) { - this.lowerBound.x = Math.min(aabb1.lowerBound.x, aabb2.lowerBound.x); - this.lowerBound.y = Math.min(aabb1.lowerBound.y, aabb2.lowerBound.y); - this.upperBound.x = Math.max(aabb1.upperBound.x, aabb2.upperBound.x); - this.upperBound.y = Math.max(aabb1.upperBound.y, aabb2.upperBound.y); - } - b2Bound.b2Bound = function () {}; - b2Bound.prototype.IsLower = function () { - return (this.value & 1) == 0; - } - b2Bound.prototype.IsUpper = function () { - return (this.value & 1) == 1; - } - b2Bound.prototype.Swap = function (b) { - var tempValue = this.value; - var tempProxy = this.proxy; - var tempStabbingCount = this.stabbingCount; - this.value = b.value; - this.proxy = b.proxy; - this.stabbingCount = b.stabbingCount; - b.value = tempValue; - b.proxy = tempProxy; - b.stabbingCount = tempStabbingCount; - } - b2BoundValues.b2BoundValues = function () {}; - b2BoundValues.prototype.b2BoundValues = function () { - this.lowerValues = new Vector_a2j_Number(); - this.lowerValues[0] = 0.0; - this.lowerValues[1] = 0.0; - this.upperValues = new Vector_a2j_Number(); - this.upperValues[0] = 0.0; - this.upperValues[1] = 0.0; - } - b2Collision.b2Collision = function () {}; - b2Collision.ClipSegmentToLine = function (vOut, vIn, normal, offset) { - if (offset === undefined) offset = 0; - var cv; - var numOut = 0; - cv = vIn[0]; - var vIn0 = cv.v; - cv = vIn[1]; - var vIn1 = cv.v; - var distance0 = normal.x * vIn0.x + normal.y * vIn0.y - offset; - var distance1 = normal.x * vIn1.x + normal.y * vIn1.y - offset; - if (distance0 <= 0.0) vOut[numOut++].Set(vIn[0]); - if (distance1 <= 0.0) vOut[numOut++].Set(vIn[1]); - if (distance0 * distance1 < 0.0) { - var interp = distance0 / (distance0 - distance1); - cv = vOut[numOut]; - var tVec = cv.v; - tVec.x = vIn0.x + interp * (vIn1.x - vIn0.x); - tVec.y = vIn0.y + interp * (vIn1.y - vIn0.y); - cv = vOut[numOut]; - var cv2; - if (distance0 > 0.0) { - cv2 = vIn[0]; - cv.id = cv2.id; - } - else { - cv2 = vIn[1]; - cv.id = cv2.id; - }++numOut; - } - return numOut; - } - b2Collision.EdgeSeparation = function (poly1, xf1, edge1, poly2, xf2) { - if (edge1 === undefined) edge1 = 0; - var count1 = parseInt(poly1.m_vertexCount); - var vertices1 = poly1.m_vertices; - var normals1 = poly1.m_normals; - var count2 = parseInt(poly2.m_vertexCount); - var vertices2 = poly2.m_vertices; - var tMat; - var tVec; - tMat = xf1.R; - tVec = normals1[edge1]; - var normal1WorldX = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var normal1WorldY = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tMat = xf2.R; - var normal1X = (tMat.col1.x * normal1WorldX + tMat.col1.y * normal1WorldY); - var normal1Y = (tMat.col2.x * normal1WorldX + tMat.col2.y * normal1WorldY); - var index = 0; - var minDot = Number.MAX_VALUE; - for (var i = 0; i < count2; ++i) { - tVec = vertices2[i]; - var dot = tVec.x * normal1X + tVec.y * normal1Y; - if (dot < minDot) { - minDot = dot; - index = i; - } - } - tVec = vertices1[edge1]; - tMat = xf1.R; - var v1X = xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var v1Y = xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tVec = vertices2[index]; - tMat = xf2.R; - var v2X = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var v2Y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - v2X -= v1X; - v2Y -= v1Y; - var separation = v2X * normal1WorldX + v2Y * normal1WorldY; - return separation; - } - b2Collision.FindMaxSeparation = function (edgeIndex, poly1, xf1, poly2, xf2) { - var count1 = parseInt(poly1.m_vertexCount); - var normals1 = poly1.m_normals; - var tVec; - var tMat; - tMat = xf2.R; - tVec = poly2.m_centroid; - var dX = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var dY = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tMat = xf1.R; - tVec = poly1.m_centroid; - dX -= xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - dY -= xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - var dLocal1X = (dX * xf1.R.col1.x + dY * xf1.R.col1.y); - var dLocal1Y = (dX * xf1.R.col2.x + dY * xf1.R.col2.y); - var edge = 0; - var maxDot = (-Number.MAX_VALUE); - for (var i = 0; i < count1; ++i) { - tVec = normals1[i]; - var dot = (tVec.x * dLocal1X + tVec.y * dLocal1Y); - if (dot > maxDot) { - maxDot = dot; - edge = i; - } - } - var s = b2Collision.EdgeSeparation(poly1, xf1, edge, poly2, xf2); - var prevEdge = parseInt(edge - 1 >= 0 ? edge - 1 : count1 - 1); - var sPrev = b2Collision.EdgeSeparation(poly1, xf1, prevEdge, poly2, xf2); - var nextEdge = parseInt(edge + 1 < count1 ? edge + 1 : 0); - var sNext = b2Collision.EdgeSeparation(poly1, xf1, nextEdge, poly2, xf2); - var bestEdge = 0; - var bestSeparation = 0; - var increment = 0; - if (sPrev > s && sPrev > sNext) { - increment = (-1); - bestEdge = prevEdge; - bestSeparation = sPrev; - } - else if (sNext > s) { - increment = 1; - bestEdge = nextEdge; - bestSeparation = sNext; - } - else { - edgeIndex[0] = edge; - return s; - } - while (true) { - if (increment == (-1)) edge = bestEdge - 1 >= 0 ? bestEdge - 1 : count1 - 1; - else edge = bestEdge + 1 < count1 ? bestEdge + 1 : 0;s = b2Collision.EdgeSeparation(poly1, xf1, edge, poly2, xf2); - if (s > bestSeparation) { - bestEdge = edge; - bestSeparation = s; - } - else { - break; - } - } - edgeIndex[0] = bestEdge; - return bestSeparation; - } - b2Collision.FindIncidentEdge = function (c, poly1, xf1, edge1, poly2, xf2) { - if (edge1 === undefined) edge1 = 0; - var count1 = parseInt(poly1.m_vertexCount); - var normals1 = poly1.m_normals; - var count2 = parseInt(poly2.m_vertexCount); - var vertices2 = poly2.m_vertices; - var normals2 = poly2.m_normals; - var tMat; - var tVec; - tMat = xf1.R; - tVec = normals1[edge1]; - var normal1X = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var normal1Y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tMat = xf2.R; - var tX = (tMat.col1.x * normal1X + tMat.col1.y * normal1Y); - normal1Y = (tMat.col2.x * normal1X + tMat.col2.y * normal1Y); - normal1X = tX; - var index = 0; - var minDot = Number.MAX_VALUE; - for (var i = 0; i < count2; ++i) { - tVec = normals2[i]; - var dot = (normal1X * tVec.x + normal1Y * tVec.y); - if (dot < minDot) { - minDot = dot; - index = i; - } - } - var tClip; - var i1 = parseInt(index); - var i2 = parseInt(i1 + 1 < count2 ? i1 + 1 : 0); - tClip = c[0]; - tVec = vertices2[i1]; - tMat = xf2.R; - tClip.v.x = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - tClip.v.y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tClip.id.features.referenceEdge = edge1; - tClip.id.features.incidentEdge = i1; - tClip.id.features.incidentVertex = 0; - tClip = c[1]; - tVec = vertices2[i2]; - tMat = xf2.R; - tClip.v.x = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - tClip.v.y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tClip.id.features.referenceEdge = edge1; - tClip.id.features.incidentEdge = i2; - tClip.id.features.incidentVertex = 1; - } - b2Collision.MakeClipPointVector = function () { - var r = new Vector(2); - r[0] = new ClipVertex(); - r[1] = new ClipVertex(); - return r; - } - b2Collision.CollidePolygons = function (manifold, polyA, xfA, polyB, xfB) { - var cv; - manifold.m_pointCount = 0; - var totalRadius = polyA.m_radius + polyB.m_radius; - var edgeA = 0; - b2Collision.s_edgeAO[0] = edgeA; - var separationA = b2Collision.FindMaxSeparation(b2Collision.s_edgeAO, polyA, xfA, polyB, xfB); - edgeA = b2Collision.s_edgeAO[0]; - if (separationA > totalRadius) return; - var edgeB = 0; - b2Collision.s_edgeBO[0] = edgeB; - var separationB = b2Collision.FindMaxSeparation(b2Collision.s_edgeBO, polyB, xfB, polyA, xfA); - edgeB = b2Collision.s_edgeBO[0]; - if (separationB > totalRadius) return; - var poly1; - var poly2; - var xf1; - var xf2; - var edge1 = 0; - var flip = 0; - var k_relativeTol = 0.98; - var k_absoluteTol = 0.001; - var tMat; - if (separationB > k_relativeTol * separationA + k_absoluteTol) { - poly1 = polyB; - poly2 = polyA; - xf1 = xfB; - xf2 = xfA; - edge1 = edgeB; - manifold.m_type = b2Manifold.e_faceB; - flip = 1; - } - else { - poly1 = polyA; - poly2 = polyB; - xf1 = xfA; - xf2 = xfB; - edge1 = edgeA; - manifold.m_type = b2Manifold.e_faceA; - flip = 0; - } - var incidentEdge = b2Collision.s_incidentEdge; - b2Collision.FindIncidentEdge(incidentEdge, poly1, xf1, edge1, poly2, xf2); - var count1 = parseInt(poly1.m_vertexCount); - var vertices1 = poly1.m_vertices; - var local_v11 = vertices1[edge1]; - var local_v12; - if (edge1 + 1 < count1) { - local_v12 = vertices1[parseInt(edge1 + 1)]; - } - else { - local_v12 = vertices1[0]; - } - var localTangent = b2Collision.s_localTangent; - localTangent.Set(local_v12.x - local_v11.x, local_v12.y - local_v11.y); - localTangent.Normalize(); - var localNormal = b2Collision.s_localNormal; - localNormal.x = localTangent.y; - localNormal.y = (-localTangent.x); - var planePoint = b2Collision.s_planePoint; - planePoint.Set(0.5 * (local_v11.x + local_v12.x), 0.5 * (local_v11.y + local_v12.y)); - var tangent = b2Collision.s_tangent; - tMat = xf1.R; - tangent.x = (tMat.col1.x * localTangent.x + tMat.col2.x * localTangent.y); - tangent.y = (tMat.col1.y * localTangent.x + tMat.col2.y * localTangent.y); - var tangent2 = b2Collision.s_tangent2; - tangent2.x = (-tangent.x); - tangent2.y = (-tangent.y); - var normal = b2Collision.s_normal; - normal.x = tangent.y; - normal.y = (-tangent.x); - var v11 = b2Collision.s_v11; - var v12 = b2Collision.s_v12; - v11.x = xf1.position.x + (tMat.col1.x * local_v11.x + tMat.col2.x * local_v11.y); - v11.y = xf1.position.y + (tMat.col1.y * local_v11.x + tMat.col2.y * local_v11.y); - v12.x = xf1.position.x + (tMat.col1.x * local_v12.x + tMat.col2.x * local_v12.y); - v12.y = xf1.position.y + (tMat.col1.y * local_v12.x + tMat.col2.y * local_v12.y); - var frontOffset = normal.x * v11.x + normal.y * v11.y; - var sideOffset1 = (-tangent.x * v11.x) - tangent.y * v11.y + totalRadius; - var sideOffset2 = tangent.x * v12.x + tangent.y * v12.y + totalRadius; - var clipPoints1 = b2Collision.s_clipPoints1; - var clipPoints2 = b2Collision.s_clipPoints2; - var np = 0; - np = b2Collision.ClipSegmentToLine(clipPoints1, incidentEdge, tangent2, sideOffset1); - if (np < 2) return; - np = b2Collision.ClipSegmentToLine(clipPoints2, clipPoints1, tangent, sideOffset2); - if (np < 2) return; - manifold.m_localPlaneNormal.SetV(localNormal); - manifold.m_localPoint.SetV(planePoint); - var pointCount = 0; - for (var i = 0; i < b2Settings.b2_maxManifoldPoints; ++i) { - cv = clipPoints2[i]; - var separation = normal.x * cv.v.x + normal.y * cv.v.y - frontOffset; - if (separation <= totalRadius) { - var cp = manifold.m_points[pointCount]; - tMat = xf2.R; - var tX = cv.v.x - xf2.position.x; - var tY = cv.v.y - xf2.position.y; - cp.m_localPoint.x = (tX * tMat.col1.x + tY * tMat.col1.y); - cp.m_localPoint.y = (tX * tMat.col2.x + tY * tMat.col2.y); - cp.m_id.Set(cv.id); - cp.m_id.features.flip = flip; - ++pointCount; - } - } - manifold.m_pointCount = pointCount; - } - b2Collision.CollideCircles = function (manifold, circle1, xf1, circle2, xf2) { - manifold.m_pointCount = 0; - var tMat; - var tVec; - tMat = xf1.R; - tVec = circle1.m_p; - var p1X = xf1.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var p1Y = xf1.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tMat = xf2.R; - tVec = circle2.m_p; - var p2X = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var p2Y = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - var dX = p2X - p1X; - var dY = p2Y - p1Y; - var distSqr = dX * dX + dY * dY; - var radius = circle1.m_radius + circle2.m_radius; - if (distSqr > radius * radius) { - return; - } - manifold.m_type = b2Manifold.e_circles; - manifold.m_localPoint.SetV(circle1.m_p); - manifold.m_localPlaneNormal.SetZero(); - manifold.m_pointCount = 1; - manifold.m_points[0].m_localPoint.SetV(circle2.m_p); - manifold.m_points[0].m_id.key = 0; - } - b2Collision.CollidePolygonAndCircle = function (manifold, polygon, xf1, circle, xf2) { - manifold.m_pointCount = 0; - var tPoint; - var dX = 0; - var dY = 0; - var positionX = 0; - var positionY = 0; - var tVec; - var tMat; - tMat = xf2.R; - tVec = circle.m_p; - var cX = xf2.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var cY = xf2.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - dX = cX - xf1.position.x; - dY = cY - xf1.position.y; - tMat = xf1.R; - var cLocalX = (dX * tMat.col1.x + dY * tMat.col1.y); - var cLocalY = (dX * tMat.col2.x + dY * tMat.col2.y); - var dist = 0; - var normalIndex = 0; - var separation = (-Number.MAX_VALUE); - var radius = polygon.m_radius + circle.m_radius; - var vertexCount = parseInt(polygon.m_vertexCount); - var vertices = polygon.m_vertices; - var normals = polygon.m_normals; - for (var i = 0; i < vertexCount; ++i) { - tVec = vertices[i]; - dX = cLocalX - tVec.x; - dY = cLocalY - tVec.y; - tVec = normals[i]; - var s = tVec.x * dX + tVec.y * dY; - if (s > radius) { - return; - } - if (s > separation) { - separation = s; - normalIndex = i; - } - } - var vertIndex1 = parseInt(normalIndex); - var vertIndex2 = parseInt(vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0); - var v1 = vertices[vertIndex1]; - var v2 = vertices[vertIndex2]; - if (separation < Number.MIN_VALUE) { - manifold.m_pointCount = 1; - manifold.m_type = b2Manifold.e_faceA; - manifold.m_localPlaneNormal.SetV(normals[normalIndex]); - manifold.m_localPoint.x = 0.5 * (v1.x + v2.x); - manifold.m_localPoint.y = 0.5 * (v1.y + v2.y); - manifold.m_points[0].m_localPoint.SetV(circle.m_p); - manifold.m_points[0].m_id.key = 0; - return; - } - var u1 = (cLocalX - v1.x) * (v2.x - v1.x) + (cLocalY - v1.y) * (v2.y - v1.y); - var u2 = (cLocalX - v2.x) * (v1.x - v2.x) + (cLocalY - v2.y) * (v1.y - v2.y); - if (u1 <= 0.0) { - if ((cLocalX - v1.x) * (cLocalX - v1.x) + (cLocalY - v1.y) * (cLocalY - v1.y) > radius * radius) return; - manifold.m_pointCount = 1; - manifold.m_type = b2Manifold.e_faceA; - manifold.m_localPlaneNormal.x = cLocalX - v1.x; - manifold.m_localPlaneNormal.y = cLocalY - v1.y; - manifold.m_localPlaneNormal.Normalize(); - manifold.m_localPoint.SetV(v1); - manifold.m_points[0].m_localPoint.SetV(circle.m_p); - manifold.m_points[0].m_id.key = 0; - } - else if (u2 <= 0) { - if ((cLocalX - v2.x) * (cLocalX - v2.x) + (cLocalY - v2.y) * (cLocalY - v2.y) > radius * radius) return; - manifold.m_pointCount = 1; - manifold.m_type = b2Manifold.e_faceA; - manifold.m_localPlaneNormal.x = cLocalX - v2.x; - manifold.m_localPlaneNormal.y = cLocalY - v2.y; - manifold.m_localPlaneNormal.Normalize(); - manifold.m_localPoint.SetV(v2); - manifold.m_points[0].m_localPoint.SetV(circle.m_p); - manifold.m_points[0].m_id.key = 0; - } - else { - var faceCenterX = 0.5 * (v1.x + v2.x); - var faceCenterY = 0.5 * (v1.y + v2.y); - separation = (cLocalX - faceCenterX) * normals[vertIndex1].x + (cLocalY - faceCenterY) * normals[vertIndex1].y; - if (separation > radius) return; - manifold.m_pointCount = 1; - manifold.m_type = b2Manifold.e_faceA; - manifold.m_localPlaneNormal.x = normals[vertIndex1].x; - manifold.m_localPlaneNormal.y = normals[vertIndex1].y; - manifold.m_localPlaneNormal.Normalize(); - manifold.m_localPoint.Set(faceCenterX, faceCenterY); - manifold.m_points[0].m_localPoint.SetV(circle.m_p); - manifold.m_points[0].m_id.key = 0; - } - } - b2Collision.TestOverlap = function (a, b) { - var t1 = b.lowerBound; - var t2 = a.upperBound; - var d1X = t1.x - t2.x; - var d1Y = t1.y - t2.y; - t1 = a.lowerBound; - t2 = b.upperBound; - var d2X = t1.x - t2.x; - var d2Y = t1.y - t2.y; - if (d1X > 0.0 || d1Y > 0.0) return false; - if (d2X > 0.0 || d2Y > 0.0) return false; - return true; - } - Box2D.postDefs.push(function () { - Box2D.Collision.b2Collision.s_incidentEdge = b2Collision.MakeClipPointVector(); - Box2D.Collision.b2Collision.s_clipPoints1 = b2Collision.MakeClipPointVector(); - Box2D.Collision.b2Collision.s_clipPoints2 = b2Collision.MakeClipPointVector(); - Box2D.Collision.b2Collision.s_edgeAO = new Vector_a2j_Number(1); - Box2D.Collision.b2Collision.s_edgeBO = new Vector_a2j_Number(1); - Box2D.Collision.b2Collision.s_localTangent = new b2Vec2(); - Box2D.Collision.b2Collision.s_localNormal = new b2Vec2(); - Box2D.Collision.b2Collision.s_planePoint = new b2Vec2(); - Box2D.Collision.b2Collision.s_normal = new b2Vec2(); - Box2D.Collision.b2Collision.s_tangent = new b2Vec2(); - Box2D.Collision.b2Collision.s_tangent2 = new b2Vec2(); - Box2D.Collision.b2Collision.s_v11 = new b2Vec2(); - Box2D.Collision.b2Collision.s_v12 = new b2Vec2(); - Box2D.Collision.b2Collision.b2CollidePolyTempVec = new b2Vec2(); - Box2D.Collision.b2Collision.b2_nullFeature = 0x000000ff; - }); - b2ContactID.b2ContactID = function () { - this.features = new Features(); - }; - b2ContactID.prototype.b2ContactID = function () { - this.features._m_id = this; - } - b2ContactID.prototype.Set = function (id) { - this.key = id._key; - } - b2ContactID.prototype.Copy = function () { - var id = new b2ContactID(); - id.key = this.key; - return id; - } - Object.defineProperty(b2ContactID.prototype, 'key', { - enumerable: false, - configurable: true, - get: function () { - return this._key; - } - }); - Object.defineProperty(b2ContactID.prototype, 'key', { - enumerable: false, - configurable: true, - set: function (value) { - if (value === undefined) value = 0; - this._key = value; - this.features._referenceEdge = this._key & 0x000000ff; - this.features._incidentEdge = ((this._key & 0x0000ff00) >> 8) & 0x000000ff; - this.features._incidentVertex = ((this._key & 0x00ff0000) >> 16) & 0x000000ff; - this.features._flip = ((this._key & 0xff000000) >> 24) & 0x000000ff; - } - }); - b2ContactPoint.b2ContactPoint = function () { - this.position = new b2Vec2(); - this.velocity = new b2Vec2(); - this.normal = new b2Vec2(); - this.id = new b2ContactID(); - }; - b2Distance.b2Distance = function () {}; - b2Distance.Distance = function (output, cache, input) { - ++b2Distance.b2_gjkCalls; - var proxyA = input.proxyA; - var proxyB = input.proxyB; - var transformA = input.transformA; - var transformB = input.transformB; - var simplex = b2Distance.s_simplex; - simplex.ReadCache(cache, proxyA, transformA, proxyB, transformB); - var vertices = simplex.m_vertices; - var k_maxIters = 20; - var saveA = b2Distance.s_saveA; - var saveB = b2Distance.s_saveB; - var saveCount = 0; - var closestPoint = simplex.GetClosestPoint(); - var distanceSqr1 = closestPoint.LengthSquared(); - var distanceSqr2 = distanceSqr1; - var i = 0; - var p; - var iter = 0; - while (iter < k_maxIters) { - saveCount = simplex.m_count; - for (i = 0; - i < saveCount; i++) { - saveA[i] = vertices[i].indexA; - saveB[i] = vertices[i].indexB; - } - switch (simplex.m_count) { - case 1: - break; - case 2: - simplex.Solve2(); - break; - case 3: - simplex.Solve3(); - break; - default: - b2Settings.b2Assert(false); - } - if (simplex.m_count == 3) { - break; - } - p = simplex.GetClosestPoint(); - distanceSqr2 = p.LengthSquared(); - if (distanceSqr2 > distanceSqr1) {} - distanceSqr1 = distanceSqr2; - var d = simplex.GetSearchDirection(); - if (d.LengthSquared() < Number.MIN_VALUE * Number.MIN_VALUE) { - break; - } - var vertex = vertices[simplex.m_count]; - vertex.indexA = proxyA.GetSupport(b2Math.MulTMV(transformA.R, d.GetNegative())); - vertex.wA = b2Math.MulX(transformA, proxyA.GetVertex(vertex.indexA)); - vertex.indexB = proxyB.GetSupport(b2Math.MulTMV(transformB.R, d)); - vertex.wB = b2Math.MulX(transformB, proxyB.GetVertex(vertex.indexB)); - vertex.w = b2Math.SubtractVV(vertex.wB, vertex.wA); - ++iter; - ++b2Distance.b2_gjkIters; - var duplicate = false; - for (i = 0; - i < saveCount; i++) { - if (vertex.indexA == saveA[i] && vertex.indexB == saveB[i]) { - duplicate = true; - break; - } - } - if (duplicate) { - break; - }++simplex.m_count; - } - b2Distance.b2_gjkMaxIters = b2Math.Max(b2Distance.b2_gjkMaxIters, iter); - simplex.GetWitnessPoints(output.pointA, output.pointB); - output.distance = b2Math.SubtractVV(output.pointA, output.pointB).Length(); - output.iterations = iter; - simplex.WriteCache(cache); - if (input.useRadii) { - var rA = proxyA.m_radius; - var rB = proxyB.m_radius; - if (output.distance > rA + rB && output.distance > Number.MIN_VALUE) { - output.distance -= rA + rB; - var normal = b2Math.SubtractVV(output.pointB, output.pointA); - normal.Normalize(); - output.pointA.x += rA * normal.x; - output.pointA.y += rA * normal.y; - output.pointB.x -= rB * normal.x; - output.pointB.y -= rB * normal.y; - } - else { - p = new b2Vec2(); - p.x = .5 * (output.pointA.x + output.pointB.x); - p.y = .5 * (output.pointA.y + output.pointB.y); - output.pointA.x = output.pointB.x = p.x; - output.pointA.y = output.pointB.y = p.y; - output.distance = 0.0; - } - } - } - Box2D.postDefs.push(function () { - Box2D.Collision.b2Distance.s_simplex = new b2Simplex(); - Box2D.Collision.b2Distance.s_saveA = new Vector_a2j_Number(3); - Box2D.Collision.b2Distance.s_saveB = new Vector_a2j_Number(3); - }); - b2DistanceInput.b2DistanceInput = function () {}; - b2DistanceOutput.b2DistanceOutput = function () { - this.pointA = new b2Vec2(); - this.pointB = new b2Vec2(); - }; - b2DistanceProxy.b2DistanceProxy = function () {}; - b2DistanceProxy.prototype.Set = function (shape) { - switch (shape.GetType()) { - case b2Shape.e_circleShape: - { - var circle = (shape instanceof b2CircleShape ? shape : null); - this.m_vertices = new Vector(1, true); - this.m_vertices[0] = circle.m_p; - this.m_count = 1; - this.m_radius = circle.m_radius; - } - break; - case b2Shape.e_polygonShape: - { - var polygon = (shape instanceof b2PolygonShape ? shape : null); - this.m_vertices = polygon.m_vertices; - this.m_count = polygon.m_vertexCount; - this.m_radius = polygon.m_radius; - } - break; - default: - b2Settings.b2Assert(false); - } - } - b2DistanceProxy.prototype.GetSupport = function (d) { - var bestIndex = 0; - var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y; - for (var i = 1; i < this.m_count; ++i) { - var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y; - if (value > bestValue) { - bestIndex = i; - bestValue = value; - } - } - return bestIndex; - } - b2DistanceProxy.prototype.GetSupportVertex = function (d) { - var bestIndex = 0; - var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y; - for (var i = 1; i < this.m_count; ++i) { - var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y; - if (value > bestValue) { - bestIndex = i; - bestValue = value; - } - } - return this.m_vertices[bestIndex]; - } - b2DistanceProxy.prototype.GetVertexCount = function () { - return this.m_count; - } - b2DistanceProxy.prototype.GetVertex = function (index) { - if (index === undefined) index = 0; - b2Settings.b2Assert(0 <= index && index < this.m_count); - return this.m_vertices[index]; - } - b2DynamicTree.b2DynamicTree = function () {}; - b2DynamicTree.prototype.b2DynamicTree = function () { - this.m_root = null; - this.m_freeList = null; - this.m_path = 0; - this.m_insertionCount = 0; - } - b2DynamicTree.prototype.CreateProxy = function (aabb, userData) { - var node = this.AllocateNode(); - var extendX = b2Settings.b2_aabbExtension; - var extendY = b2Settings.b2_aabbExtension; - node.aabb.lowerBound.x = aabb.lowerBound.x - extendX; - node.aabb.lowerBound.y = aabb.lowerBound.y - extendY; - node.aabb.upperBound.x = aabb.upperBound.x + extendX; - node.aabb.upperBound.y = aabb.upperBound.y + extendY; - node.userData = userData; - this.InsertLeaf(node); - return node; - } - b2DynamicTree.prototype.DestroyProxy = function (proxy) { - this.RemoveLeaf(proxy); - this.FreeNode(proxy); - } - b2DynamicTree.prototype.MoveProxy = function (proxy, aabb, displacement) { - b2Settings.b2Assert(proxy.IsLeaf()); - if (proxy.aabb.Contains(aabb)) { - return false; - } - this.RemoveLeaf(proxy); - var extendX = b2Settings.b2_aabbExtension + b2Settings.b2_aabbMultiplier * (displacement.x > 0 ? displacement.x : (-displacement.x)); - var extendY = b2Settings.b2_aabbExtension + b2Settings.b2_aabbMultiplier * (displacement.y > 0 ? displacement.y : (-displacement.y)); - proxy.aabb.lowerBound.x = aabb.lowerBound.x - extendX; - proxy.aabb.lowerBound.y = aabb.lowerBound.y - extendY; - proxy.aabb.upperBound.x = aabb.upperBound.x + extendX; - proxy.aabb.upperBound.y = aabb.upperBound.y + extendY; - this.InsertLeaf(proxy); - return true; - } - b2DynamicTree.prototype.Rebalance = function (iterations) { - if (iterations === undefined) iterations = 0; - if (this.m_root == null) return; - for (var i = 0; i < iterations; i++) { - var node = this.m_root; - var bit = 0; - while (node.IsLeaf() == false) { - node = (this.m_path >> bit) & 1 ? node.child2 : node.child1; - bit = (bit + 1) & 31; - }++this.m_path; - this.RemoveLeaf(node); - this.InsertLeaf(node); - } - } - b2DynamicTree.prototype.GetFatAABB = function (proxy) { - return proxy.aabb; - } - b2DynamicTree.prototype.GetUserData = function (proxy) { - return proxy.userData; - } - b2DynamicTree.prototype.Query = function (callback, aabb) { - if (this.m_root == null) return; - var stack = new Vector(); - var count = 0; - stack[count++] = this.m_root; - while (count > 0) { - var node = stack[--count]; - if (node.aabb.TestOverlap(aabb)) { - if (node.IsLeaf()) { - var proceed = callback(node); - if (!proceed) return; - } - else { - stack[count++] = node.child1; - stack[count++] = node.child2; - } - } - } - } - b2DynamicTree.prototype.RayCast = function (callback, input) { - if (this.m_root == null) return; - var p1 = input.p1; - var p2 = input.p2; - var r = b2Math.SubtractVV(p1, p2); - r.Normalize(); - var v = b2Math.CrossFV(1.0, r); - var abs_v = b2Math.AbsV(v); - var maxFraction = input.maxFraction; - var segmentAABB = new b2AABB(); - var tX = 0; - var tY = 0; { - tX = p1.x + maxFraction * (p2.x - p1.x); - tY = p1.y + maxFraction * (p2.y - p1.y); - segmentAABB.lowerBound.x = Math.min(p1.x, tX); - segmentAABB.lowerBound.y = Math.min(p1.y, tY); - segmentAABB.upperBound.x = Math.max(p1.x, tX); - segmentAABB.upperBound.y = Math.max(p1.y, tY); - } - var stack = new Vector(); - var count = 0; - stack[count++] = this.m_root; - while (count > 0) { - var node = stack[--count]; - if (node.aabb.TestOverlap(segmentAABB) == false) { - continue; - } - var c = node.aabb.GetCenter(); - var h = node.aabb.GetExtents(); - var separation = Math.abs(v.x * (p1.x - c.x) + v.y * (p1.y - c.y)) - abs_v.x * h.x - abs_v.y * h.y; - if (separation > 0.0) continue; - if (node.IsLeaf()) { - var subInput = new b2RayCastInput(); - subInput.p1 = input.p1; - subInput.p2 = input.p2; - subInput.maxFraction = input.maxFraction; - maxFraction = callback(subInput, node); - if (maxFraction == 0.0) return; - if (maxFraction > 0.0) { - tX = p1.x + maxFraction * (p2.x - p1.x); - tY = p1.y + maxFraction * (p2.y - p1.y); - segmentAABB.lowerBound.x = Math.min(p1.x, tX); - segmentAABB.lowerBound.y = Math.min(p1.y, tY); - segmentAABB.upperBound.x = Math.max(p1.x, tX); - segmentAABB.upperBound.y = Math.max(p1.y, tY); - } - } - else { - stack[count++] = node.child1; - stack[count++] = node.child2; - } - } - } - b2DynamicTree.prototype.AllocateNode = function () { - if (this.m_freeList) { - var node = this.m_freeList; - this.m_freeList = node.parent; - node.parent = null; - node.child1 = null; - node.child2 = null; - return node; - } - return new b2DynamicTreeNode(); - } - b2DynamicTree.prototype.FreeNode = function (node) { - node.parent = this.m_freeList; - this.m_freeList = node; - } - b2DynamicTree.prototype.InsertLeaf = function (leaf) { - ++this.m_insertionCount; - if (this.m_root == null) { - this.m_root = leaf; - this.m_root.parent = null; - return; - } - var center = leaf.aabb.GetCenter(); - var sibling = this.m_root; - if (sibling.IsLeaf() == false) { - do { - var child1 = sibling.child1; - var child2 = sibling.child2; - var norm1 = Math.abs((child1.aabb.lowerBound.x + child1.aabb.upperBound.x) / 2 - center.x) + Math.abs((child1.aabb.lowerBound.y + child1.aabb.upperBound.y) / 2 - center.y); - var norm2 = Math.abs((child2.aabb.lowerBound.x + child2.aabb.upperBound.x) / 2 - center.x) + Math.abs((child2.aabb.lowerBound.y + child2.aabb.upperBound.y) / 2 - center.y); - if (norm1 < norm2) { - sibling = child1; - } - else { - sibling = child2; - } - } - while (sibling.IsLeaf() == false) - } - var node1 = sibling.parent; - var node2 = this.AllocateNode(); - node2.parent = node1; - node2.userData = null; - node2.aabb.Combine(leaf.aabb, sibling.aabb); - if (node1) { - if (sibling.parent.child1 == sibling) { - node1.child1 = node2; - } - else { - node1.child2 = node2; - } - node2.child1 = sibling; - node2.child2 = leaf; - sibling.parent = node2; - leaf.parent = node2; - do { - if (node1.aabb.Contains(node2.aabb)) break; - node1.aabb.Combine(node1.child1.aabb, node1.child2.aabb); - node2 = node1; - node1 = node1.parent; - } - while (node1) - } - else { - node2.child1 = sibling; - node2.child2 = leaf; - sibling.parent = node2; - leaf.parent = node2; - this.m_root = node2; - } - } - b2DynamicTree.prototype.RemoveLeaf = function (leaf) { - if (leaf == this.m_root) { - this.m_root = null; - return; - } - var node2 = leaf.parent; - var node1 = node2.parent; - var sibling; - if (node2.child1 == leaf) { - sibling = node2.child2; - } - else { - sibling = node2.child1; - } - if (node1) { - if (node1.child1 == node2) { - node1.child1 = sibling; - } - else { - node1.child2 = sibling; - } - sibling.parent = node1; - this.FreeNode(node2); - while (node1) { - var oldAABB = node1.aabb; - node1.aabb = b2AABB.Combine(node1.child1.aabb, node1.child2.aabb); - if (oldAABB.Contains(node1.aabb)) break; - node1 = node1.parent; - } - } - else { - this.m_root = sibling; - sibling.parent = null; - this.FreeNode(node2); - } - } - b2DynamicTreeBroadPhase.b2DynamicTreeBroadPhase = function () { - this.m_tree = new b2DynamicTree(); - this.m_moveBuffer = new Vector(); - this.m_pairBuffer = new Vector(); - this.m_pairCount = 0; - }; - b2DynamicTreeBroadPhase.prototype.CreateProxy = function (aabb, userData) { - var proxy = this.m_tree.CreateProxy(aabb, userData); - ++this.m_proxyCount; - this.BufferMove(proxy); - return proxy; - } - b2DynamicTreeBroadPhase.prototype.DestroyProxy = function (proxy) { - this.UnBufferMove(proxy); - --this.m_proxyCount; - this.m_tree.DestroyProxy(proxy); - } - b2DynamicTreeBroadPhase.prototype.MoveProxy = function (proxy, aabb, displacement) { - var buffer = this.m_tree.MoveProxy(proxy, aabb, displacement); - if (buffer) { - this.BufferMove(proxy); - } - } - b2DynamicTreeBroadPhase.prototype.TestOverlap = function (proxyA, proxyB) { - var aabbA = this.m_tree.GetFatAABB(proxyA); - var aabbB = this.m_tree.GetFatAABB(proxyB); - return aabbA.TestOverlap(aabbB); - } - b2DynamicTreeBroadPhase.prototype.GetUserData = function (proxy) { - return this.m_tree.GetUserData(proxy); - } - b2DynamicTreeBroadPhase.prototype.GetFatAABB = function (proxy) { - return this.m_tree.GetFatAABB(proxy); - } - b2DynamicTreeBroadPhase.prototype.GetProxyCount = function () { - return this.m_proxyCount; - } - b2DynamicTreeBroadPhase.prototype.UpdatePairs = function (callback) { - var __this = this; - __this.m_pairCount = 0; - var i = 0, - queryProxy; - for (i = 0; - i < __this.m_moveBuffer.length; ++i) { - queryProxy = __this.m_moveBuffer[i]; - - function QueryCallback(proxy) { - if (proxy == queryProxy) return true; - if (__this.m_pairCount == __this.m_pairBuffer.length) { - __this.m_pairBuffer[__this.m_pairCount] = new b2DynamicTreePair(); - } - var pair = __this.m_pairBuffer[__this.m_pairCount]; - pair.proxyA = proxy < queryProxy ? proxy : queryProxy; - pair.proxyB = proxy >= queryProxy ? proxy : queryProxy;++__this.m_pairCount; - return true; - }; - var fatAABB = __this.m_tree.GetFatAABB(queryProxy); - __this.m_tree.Query(QueryCallback, fatAABB); - } - __this.m_moveBuffer.length = 0; - for (var i = 0; i < __this.m_pairCount;) { - var primaryPair = __this.m_pairBuffer[i]; - var userDataA = __this.m_tree.GetUserData(primaryPair.proxyA); - var userDataB = __this.m_tree.GetUserData(primaryPair.proxyB); - callback(userDataA, userDataB); - ++i; - while (i < __this.m_pairCount) { - var pair = __this.m_pairBuffer[i]; - if (pair.proxyA != primaryPair.proxyA || pair.proxyB != primaryPair.proxyB) { - break; - }++i; - } - } - } - b2DynamicTreeBroadPhase.prototype.Query = function (callback, aabb) { - this.m_tree.Query(callback, aabb); - } - b2DynamicTreeBroadPhase.prototype.RayCast = function (callback, input) { - this.m_tree.RayCast(callback, input); - } - b2DynamicTreeBroadPhase.prototype.Validate = function () {} - b2DynamicTreeBroadPhase.prototype.Rebalance = function (iterations) { - if (iterations === undefined) iterations = 0; - this.m_tree.Rebalance(iterations); - } - b2DynamicTreeBroadPhase.prototype.BufferMove = function (proxy) { - this.m_moveBuffer[this.m_moveBuffer.length] = proxy; - } - b2DynamicTreeBroadPhase.prototype.UnBufferMove = function (proxy) { - var i = parseInt(this.m_moveBuffer.indexOf(proxy)); - this.m_moveBuffer.splice(i, 1); - } - b2DynamicTreeBroadPhase.prototype.ComparePairs = function (pair1, pair2) { - return 0; - } - b2DynamicTreeBroadPhase.__implements = {}; - b2DynamicTreeBroadPhase.__implements[IBroadPhase] = true; - b2DynamicTreeNode.b2DynamicTreeNode = function () { - this.aabb = new b2AABB(); - }; - b2DynamicTreeNode.prototype.IsLeaf = function () { - return this.child1 == null; - } - b2DynamicTreePair.b2DynamicTreePair = function () {}; - b2Manifold.b2Manifold = function () { - this.m_pointCount = 0; - }; - b2Manifold.prototype.b2Manifold = function () { - this.m_points = new Vector(b2Settings.b2_maxManifoldPoints); - for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { - this.m_points[i] = new b2ManifoldPoint(); - } - this.m_localPlaneNormal = new b2Vec2(); - this.m_localPoint = new b2Vec2(); - } - b2Manifold.prototype.Reset = function () { - for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { - ((this.m_points[i] instanceof b2ManifoldPoint ? this.m_points[i] : null)).Reset(); - } - this.m_localPlaneNormal.SetZero(); - this.m_localPoint.SetZero(); - this.m_type = 0; - this.m_pointCount = 0; - } - b2Manifold.prototype.Set = function (m) { - this.m_pointCount = m.m_pointCount; - for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { - ((this.m_points[i] instanceof b2ManifoldPoint ? this.m_points[i] : null)).Set(m.m_points[i]); - } - this.m_localPlaneNormal.SetV(m.m_localPlaneNormal); - this.m_localPoint.SetV(m.m_localPoint); - this.m_type = m.m_type; - } - b2Manifold.prototype.Copy = function () { - var copy = new b2Manifold(); - copy.Set(this); - return copy; - } - Box2D.postDefs.push(function () { - Box2D.Collision.b2Manifold.e_circles = 0x0001; - Box2D.Collision.b2Manifold.e_faceA = 0x0002; - Box2D.Collision.b2Manifold.e_faceB = 0x0004; - }); - b2ManifoldPoint.b2ManifoldPoint = function () { - this.m_localPoint = new b2Vec2(); - this.m_id = new b2ContactID(); - }; - b2ManifoldPoint.prototype.b2ManifoldPoint = function () { - this.Reset(); - } - b2ManifoldPoint.prototype.Reset = function () { - this.m_localPoint.SetZero(); - this.m_normalImpulse = 0.0; - this.m_tangentImpulse = 0.0; - this.m_id.key = 0; - } - b2ManifoldPoint.prototype.Set = function (m) { - this.m_localPoint.SetV(m.m_localPoint); - this.m_normalImpulse = m.m_normalImpulse; - this.m_tangentImpulse = m.m_tangentImpulse; - this.m_id.Set(m.m_id); - } - b2Point.b2Point = function () { - this.p = new b2Vec2(); - }; - b2Point.prototype.Support = function (xf, vX, vY) { - if (vX === undefined) vX = 0; - if (vY === undefined) vY = 0; - return this.p; - } - b2Point.prototype.GetFirstVertex = function (xf) { - return this.p; - } - b2RayCastInput.b2RayCastInput = function () { - this.p1 = new b2Vec2(); - this.p2 = new b2Vec2(); - }; - b2RayCastInput.prototype.b2RayCastInput = function (p1, p2, maxFraction) { - if (p1 === undefined) p1 = null; - if (p2 === undefined) p2 = null; - if (maxFraction === undefined) maxFraction = 1; - if (p1) this.p1.SetV(p1); - if (p2) this.p2.SetV(p2); - this.maxFraction = maxFraction; - } - b2RayCastOutput.b2RayCastOutput = function () { - this.normal = new b2Vec2(); - }; - b2Segment.b2Segment = function () { - this.p1 = new b2Vec2(); - this.p2 = new b2Vec2(); - }; - b2Segment.prototype.TestSegment = function (lambda, normal, segment, maxLambda) { - if (maxLambda === undefined) maxLambda = 0; - var s = segment.p1; - var rX = segment.p2.x - s.x; - var rY = segment.p2.y - s.y; - var dX = this.p2.x - this.p1.x; - var dY = this.p2.y - this.p1.y; - var nX = dY; - var nY = (-dX); - var k_slop = 100.0 * Number.MIN_VALUE; - var denom = (-(rX * nX + rY * nY)); - if (denom > k_slop) { - var bX = s.x - this.p1.x; - var bY = s.y - this.p1.y; - var a = (bX * nX + bY * nY); - if (0.0 <= a && a <= maxLambda * denom) { - var mu2 = (-rX * bY) + rY * bX; - if ((-k_slop * denom) <= mu2 && mu2 <= denom * (1.0 + k_slop)) { - a /= denom; - var nLen = Math.sqrt(nX * nX + nY * nY); - nX /= nLen; - nY /= nLen; - lambda[0] = a; - normal.Set(nX, nY); - return true; - } - } - } - return false; - } - b2Segment.prototype.Extend = function (aabb) { - this.ExtendForward(aabb); - this.ExtendBackward(aabb); - } - b2Segment.prototype.ExtendForward = function (aabb) { - var dX = this.p2.x - this.p1.x; - var dY = this.p2.y - this.p1.y; - var lambda = Math.min(dX > 0 ? (aabb.upperBound.x - this.p1.x) / dX : dX < 0 ? (aabb.lowerBound.x - this.p1.x) / dX : Number.POSITIVE_INFINITY, - dY > 0 ? (aabb.upperBound.y - this.p1.y) / dY : dY < 0 ? (aabb.lowerBound.y - this.p1.y) / dY : Number.POSITIVE_INFINITY); - this.p2.x = this.p1.x + dX * lambda; - this.p2.y = this.p1.y + dY * lambda; - } - b2Segment.prototype.ExtendBackward = function (aabb) { - var dX = (-this.p2.x) + this.p1.x; - var dY = (-this.p2.y) + this.p1.y; - var lambda = Math.min(dX > 0 ? (aabb.upperBound.x - this.p2.x) / dX : dX < 0 ? (aabb.lowerBound.x - this.p2.x) / dX : Number.POSITIVE_INFINITY, - dY > 0 ? (aabb.upperBound.y - this.p2.y) / dY : dY < 0 ? (aabb.lowerBound.y - this.p2.y) / dY : Number.POSITIVE_INFINITY); - this.p1.x = this.p2.x + dX * lambda; - this.p1.y = this.p2.y + dY * lambda; - } - b2SeparationFunction.b2SeparationFunction = function () { - this.m_localPoint = new b2Vec2(); - this.m_axis = new b2Vec2(); - }; - b2SeparationFunction.prototype.Initialize = function (cache, proxyA, transformA, proxyB, transformB) { - this.m_proxyA = proxyA; - this.m_proxyB = proxyB; - var count = parseInt(cache.count); - b2Settings.b2Assert(0 < count && count < 3); - var localPointA; - var localPointA1; - var localPointA2; - var localPointB; - var localPointB1; - var localPointB2; - var pointAX = 0; - var pointAY = 0; - var pointBX = 0; - var pointBY = 0; - var normalX = 0; - var normalY = 0; - var tMat; - var tVec; - var s = 0; - var sgn = 0; - if (count == 1) { - this.m_type = b2SeparationFunction.e_points; - localPointA = this.m_proxyA.GetVertex(cache.indexA[0]); - localPointB = this.m_proxyB.GetVertex(cache.indexB[0]); - tVec = localPointA; - tMat = transformA.R; - pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tVec = localPointB; - tMat = transformB.R; - pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - this.m_axis.x = pointBX - pointAX; - this.m_axis.y = pointBY - pointAY; - this.m_axis.Normalize(); - } - else if (cache.indexB[0] == cache.indexB[1]) { - this.m_type = b2SeparationFunction.e_faceA; - localPointA1 = this.m_proxyA.GetVertex(cache.indexA[0]); - localPointA2 = this.m_proxyA.GetVertex(cache.indexA[1]); - localPointB = this.m_proxyB.GetVertex(cache.indexB[0]); - this.m_localPoint.x = 0.5 * (localPointA1.x + localPointA2.x); - this.m_localPoint.y = 0.5 * (localPointA1.y + localPointA2.y); - this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointA2, localPointA1), 1.0); - this.m_axis.Normalize(); - tVec = this.m_axis; - tMat = transformA.R; - normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tVec = this.m_localPoint; - tMat = transformA.R; - pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tVec = localPointB; - tMat = transformB.R; - pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - s = (pointBX - pointAX) * normalX + (pointBY - pointAY) * normalY; - if (s < 0.0) { - this.m_axis.NegativeSelf(); - } - } - else if (cache.indexA[0] == cache.indexA[0]) { - this.m_type = b2SeparationFunction.e_faceB; - localPointB1 = this.m_proxyB.GetVertex(cache.indexB[0]); - localPointB2 = this.m_proxyB.GetVertex(cache.indexB[1]); - localPointA = this.m_proxyA.GetVertex(cache.indexA[0]); - this.m_localPoint.x = 0.5 * (localPointB1.x + localPointB2.x); - this.m_localPoint.y = 0.5 * (localPointB1.y + localPointB2.y); - this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointB2, localPointB1), 1.0); - this.m_axis.Normalize(); - tVec = this.m_axis; - tMat = transformB.R; - normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tVec = this.m_localPoint; - tMat = transformB.R; - pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tVec = localPointA; - tMat = transformA.R; - pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - s = (pointAX - pointBX) * normalX + (pointAY - pointBY) * normalY; - if (s < 0.0) { - this.m_axis.NegativeSelf(); - } - } - else { - localPointA1 = this.m_proxyA.GetVertex(cache.indexA[0]); - localPointA2 = this.m_proxyA.GetVertex(cache.indexA[1]); - localPointB1 = this.m_proxyB.GetVertex(cache.indexB[0]); - localPointB2 = this.m_proxyB.GetVertex(cache.indexB[1]); - var pA = b2Math.MulX(transformA, localPointA); - var dA = b2Math.MulMV(transformA.R, b2Math.SubtractVV(localPointA2, localPointA1)); - var pB = b2Math.MulX(transformB, localPointB); - var dB = b2Math.MulMV(transformB.R, b2Math.SubtractVV(localPointB2, localPointB1)); - var a = dA.x * dA.x + dA.y * dA.y; - var e = dB.x * dB.x + dB.y * dB.y; - var r = b2Math.SubtractVV(dB, dA); - var c = dA.x * r.x + dA.y * r.y; - var f = dB.x * r.x + dB.y * r.y; - var b = dA.x * dB.x + dA.y * dB.y; - var denom = a * e - b * b; - s = 0.0; - if (denom != 0.0) { - s = b2Math.Clamp((b * f - c * e) / denom, 0.0, 1.0); - } - var t = (b * s + f) / e; - if (t < 0.0) { - t = 0.0; - s = b2Math.Clamp((b - c) / a, 0.0, 1.0); - } - localPointA = new b2Vec2(); - localPointA.x = localPointA1.x + s * (localPointA2.x - localPointA1.x); - localPointA.y = localPointA1.y + s * (localPointA2.y - localPointA1.y); - localPointB = new b2Vec2(); - localPointB.x = localPointB1.x + s * (localPointB2.x - localPointB1.x); - localPointB.y = localPointB1.y + s * (localPointB2.y - localPointB1.y); - if (s == 0.0 || s == 1.0) { - this.m_type = b2SeparationFunction.e_faceB; - this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointB2, localPointB1), 1.0); - this.m_axis.Normalize(); - this.m_localPoint = localPointB; - tVec = this.m_axis; - tMat = transformB.R; - normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tVec = this.m_localPoint; - tMat = transformB.R; - pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tVec = localPointA; - tMat = transformA.R; - pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - sgn = (pointAX - pointBX) * normalX + (pointAY - pointBY) * normalY; - if (s < 0.0) { - this.m_axis.NegativeSelf(); - } - } - else { - this.m_type = b2SeparationFunction.e_faceA; - this.m_axis = b2Math.CrossVF(b2Math.SubtractVV(localPointA2, localPointA1), 1.0); - this.m_localPoint = localPointA; - tVec = this.m_axis; - tMat = transformA.R; - normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tVec = this.m_localPoint; - tMat = transformA.R; - pointAX = transformA.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointAY = transformA.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tVec = localPointB; - tMat = transformB.R; - pointBX = transformB.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - pointBY = transformB.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - sgn = (pointBX - pointAX) * normalX + (pointBY - pointAY) * normalY; - if (s < 0.0) { - this.m_axis.NegativeSelf(); - } - } - } - } - b2SeparationFunction.prototype.Evaluate = function (transformA, transformB) { - var axisA; - var axisB; - var localPointA; - var localPointB; - var pointA; - var pointB; - var seperation = 0; - var normal; - switch (this.m_type) { - case b2SeparationFunction.e_points: - { - axisA = b2Math.MulTMV(transformA.R, this.m_axis); - axisB = b2Math.MulTMV(transformB.R, this.m_axis.GetNegative()); - localPointA = this.m_proxyA.GetSupportVertex(axisA); - localPointB = this.m_proxyB.GetSupportVertex(axisB); - pointA = b2Math.MulX(transformA, localPointA); - pointB = b2Math.MulX(transformB, localPointB); - seperation = (pointB.x - pointA.x) * this.m_axis.x + (pointB.y - pointA.y) * this.m_axis.y; - return seperation; - } - case b2SeparationFunction.e_faceA: - { - normal = b2Math.MulMV(transformA.R, this.m_axis); - pointA = b2Math.MulX(transformA, this.m_localPoint); - axisB = b2Math.MulTMV(transformB.R, normal.GetNegative()); - localPointB = this.m_proxyB.GetSupportVertex(axisB); - pointB = b2Math.MulX(transformB, localPointB); - seperation = (pointB.x - pointA.x) * normal.x + (pointB.y - pointA.y) * normal.y; - return seperation; - } - case b2SeparationFunction.e_faceB: - { - normal = b2Math.MulMV(transformB.R, this.m_axis); - pointB = b2Math.MulX(transformB, this.m_localPoint); - axisA = b2Math.MulTMV(transformA.R, normal.GetNegative()); - localPointA = this.m_proxyA.GetSupportVertex(axisA); - pointA = b2Math.MulX(transformA, localPointA); - seperation = (pointA.x - pointB.x) * normal.x + (pointA.y - pointB.y) * normal.y; - return seperation; - } - default: - b2Settings.b2Assert(false); - return 0.0; - } - } - Box2D.postDefs.push(function () { - Box2D.Collision.b2SeparationFunction.e_points = 0x01; - Box2D.Collision.b2SeparationFunction.e_faceA = 0x02; - Box2D.Collision.b2SeparationFunction.e_faceB = 0x04; - }); - b2Simplex.b2Simplex = function () { - this.m_v1 = new b2SimplexVertex(); - this.m_v2 = new b2SimplexVertex(); - this.m_v3 = new b2SimplexVertex(); - this.m_vertices = new Vector(3); - }; - b2Simplex.prototype.b2Simplex = function () { - this.m_vertices[0] = this.m_v1; - this.m_vertices[1] = this.m_v2; - this.m_vertices[2] = this.m_v3; - } - b2Simplex.prototype.ReadCache = function (cache, proxyA, transformA, proxyB, transformB) { - b2Settings.b2Assert(0 <= cache.count && cache.count <= 3); - var wALocal; - var wBLocal; - this.m_count = cache.count; - var vertices = this.m_vertices; - for (var i = 0; i < this.m_count; i++) { - var v = vertices[i]; - v.indexA = cache.indexA[i]; - v.indexB = cache.indexB[i]; - wALocal = proxyA.GetVertex(v.indexA); - wBLocal = proxyB.GetVertex(v.indexB); - v.wA = b2Math.MulX(transformA, wALocal); - v.wB = b2Math.MulX(transformB, wBLocal); - v.w = b2Math.SubtractVV(v.wB, v.wA); - v.a = 0; - } - if (this.m_count > 1) { - var metric1 = cache.metric; - var metric2 = this.GetMetric(); - if (metric2 < .5 * metric1 || 2.0 * metric1 < metric2 || metric2 < Number.MIN_VALUE) { - this.m_count = 0; - } - } - if (this.m_count == 0) { - v = vertices[0]; - v.indexA = 0; - v.indexB = 0; - wALocal = proxyA.GetVertex(0); - wBLocal = proxyB.GetVertex(0); - v.wA = b2Math.MulX(transformA, wALocal); - v.wB = b2Math.MulX(transformB, wBLocal); - v.w = b2Math.SubtractVV(v.wB, v.wA); - this.m_count = 1; - } - } - b2Simplex.prototype.WriteCache = function (cache) { - cache.metric = this.GetMetric(); - cache.count = Box2D.parseUInt(this.m_count); - var vertices = this.m_vertices; - for (var i = 0; i < this.m_count; i++) { - cache.indexA[i] = Box2D.parseUInt(vertices[i].indexA); - cache.indexB[i] = Box2D.parseUInt(vertices[i].indexB); - } - } - b2Simplex.prototype.GetSearchDirection = function () { - switch (this.m_count) { - case 1: - return this.m_v1.w.GetNegative(); - case 2: - { - var e12 = b2Math.SubtractVV(this.m_v2.w, this.m_v1.w); - var sgn = b2Math.CrossVV(e12, this.m_v1.w.GetNegative()); - if (sgn > 0.0) { - return b2Math.CrossFV(1.0, e12); - } - else { - return b2Math.CrossVF(e12, 1.0); - } - } - default: - b2Settings.b2Assert(false); - return new b2Vec2(); - } - } - b2Simplex.prototype.GetClosestPoint = function () { - switch (this.m_count) { - case 0: - b2Settings.b2Assert(false); - return new b2Vec2(); - case 1: - return this.m_v1.w; - case 2: - return new b2Vec2(this.m_v1.a * this.m_v1.w.x + this.m_v2.a * this.m_v2.w.x, this.m_v1.a * this.m_v1.w.y + this.m_v2.a * this.m_v2.w.y); - default: - b2Settings.b2Assert(false); - return new b2Vec2(); - } - } - b2Simplex.prototype.GetWitnessPoints = function (pA, pB) { - switch (this.m_count) { - case 0: - b2Settings.b2Assert(false); - break; - case 1: - pA.SetV(this.m_v1.wA); - pB.SetV(this.m_v1.wB); - break; - case 2: - pA.x = this.m_v1.a * this.m_v1.wA.x + this.m_v2.a * this.m_v2.wA.x; - pA.y = this.m_v1.a * this.m_v1.wA.y + this.m_v2.a * this.m_v2.wA.y; - pB.x = this.m_v1.a * this.m_v1.wB.x + this.m_v2.a * this.m_v2.wB.x; - pB.y = this.m_v1.a * this.m_v1.wB.y + this.m_v2.a * this.m_v2.wB.y; - break; - case 3: - pB.x = pA.x = this.m_v1.a * this.m_v1.wA.x + this.m_v2.a * this.m_v2.wA.x + this.m_v3.a * this.m_v3.wA.x; - pB.y = pA.y = this.m_v1.a * this.m_v1.wA.y + this.m_v2.a * this.m_v2.wA.y + this.m_v3.a * this.m_v3.wA.y; - break; - default: - b2Settings.b2Assert(false); - break; - } - } - b2Simplex.prototype.GetMetric = function () { - switch (this.m_count) { - case 0: - b2Settings.b2Assert(false); - return 0.0; - case 1: - return 0.0; - case 2: - return b2Math.SubtractVV(this.m_v1.w, this.m_v2.w).Length(); - case 3: - return b2Math.CrossVV(b2Math.SubtractVV(this.m_v2.w, this.m_v1.w), b2Math.SubtractVV(this.m_v3.w, this.m_v1.w)); - default: - b2Settings.b2Assert(false); - return 0.0; - } - } - b2Simplex.prototype.Solve2 = function () { - var w1 = this.m_v1.w; - var w2 = this.m_v2.w; - var e12 = b2Math.SubtractVV(w2, w1); - var d12_2 = (-(w1.x * e12.x + w1.y * e12.y)); - if (d12_2 <= 0.0) { - this.m_v1.a = 1.0; - this.m_count = 1; - return; - } - var d12_1 = (w2.x * e12.x + w2.y * e12.y); - if (d12_1 <= 0.0) { - this.m_v2.a = 1.0; - this.m_count = 1; - this.m_v1.Set(this.m_v2); - return; - } - var inv_d12 = 1.0 / (d12_1 + d12_2); - this.m_v1.a = d12_1 * inv_d12; - this.m_v2.a = d12_2 * inv_d12; - this.m_count = 2; - } - b2Simplex.prototype.Solve3 = function () { - var w1 = this.m_v1.w; - var w2 = this.m_v2.w; - var w3 = this.m_v3.w; - var e12 = b2Math.SubtractVV(w2, w1); - var w1e12 = b2Math.Dot(w1, e12); - var w2e12 = b2Math.Dot(w2, e12); - var d12_1 = w2e12; - var d12_2 = (-w1e12); - var e13 = b2Math.SubtractVV(w3, w1); - var w1e13 = b2Math.Dot(w1, e13); - var w3e13 = b2Math.Dot(w3, e13); - var d13_1 = w3e13; - var d13_2 = (-w1e13); - var e23 = b2Math.SubtractVV(w3, w2); - var w2e23 = b2Math.Dot(w2, e23); - var w3e23 = b2Math.Dot(w3, e23); - var d23_1 = w3e23; - var d23_2 = (-w2e23); - var n123 = b2Math.CrossVV(e12, e13); - var d123_1 = n123 * b2Math.CrossVV(w2, w3); - var d123_2 = n123 * b2Math.CrossVV(w3, w1); - var d123_3 = n123 * b2Math.CrossVV(w1, w2); - if (d12_2 <= 0.0 && d13_2 <= 0.0) { - this.m_v1.a = 1.0; - this.m_count = 1; - return; - } - if (d12_1 > 0.0 && d12_2 > 0.0 && d123_3 <= 0.0) { - var inv_d12 = 1.0 / (d12_1 + d12_2); - this.m_v1.a = d12_1 * inv_d12; - this.m_v2.a = d12_2 * inv_d12; - this.m_count = 2; - return; - } - if (d13_1 > 0.0 && d13_2 > 0.0 && d123_2 <= 0.0) { - var inv_d13 = 1.0 / (d13_1 + d13_2); - this.m_v1.a = d13_1 * inv_d13; - this.m_v3.a = d13_2 * inv_d13; - this.m_count = 2; - this.m_v2.Set(this.m_v3); - return; - } - if (d12_1 <= 0.0 && d23_2 <= 0.0) { - this.m_v2.a = 1.0; - this.m_count = 1; - this.m_v1.Set(this.m_v2); - return; - } - if (d13_1 <= 0.0 && d23_1 <= 0.0) { - this.m_v3.a = 1.0; - this.m_count = 1; - this.m_v1.Set(this.m_v3); - return; - } - if (d23_1 > 0.0 && d23_2 > 0.0 && d123_1 <= 0.0) { - var inv_d23 = 1.0 / (d23_1 + d23_2); - this.m_v2.a = d23_1 * inv_d23; - this.m_v3.a = d23_2 * inv_d23; - this.m_count = 2; - this.m_v1.Set(this.m_v3); - return; - } - var inv_d123 = 1.0 / (d123_1 + d123_2 + d123_3); - this.m_v1.a = d123_1 * inv_d123; - this.m_v2.a = d123_2 * inv_d123; - this.m_v3.a = d123_3 * inv_d123; - this.m_count = 3; - } - b2SimplexCache.b2SimplexCache = function () { - this.indexA = new Vector_a2j_Number(3); - this.indexB = new Vector_a2j_Number(3); - }; - b2SimplexVertex.b2SimplexVertex = function () {}; - b2SimplexVertex.prototype.Set = function (other) { - this.wA.SetV(other.wA); - this.wB.SetV(other.wB); - this.w.SetV(other.w); - this.a = other.a; - this.indexA = other.indexA; - this.indexB = other.indexB; - } - b2TimeOfImpact.b2TimeOfImpact = function () {}; - b2TimeOfImpact.TimeOfImpact = function (input) { - ++b2TimeOfImpact.b2_toiCalls; - var proxyA = input.proxyA; - var proxyB = input.proxyB; - var sweepA = input.sweepA; - var sweepB = input.sweepB; - b2Settings.b2Assert(sweepA.t0 == sweepB.t0); - b2Settings.b2Assert(1.0 - sweepA.t0 > Number.MIN_VALUE); - var radius = proxyA.m_radius + proxyB.m_radius; - var tolerance = input.tolerance; - var alpha = 0.0; - var k_maxIterations = 1000; - var iter = 0; - var target = 0.0; - b2TimeOfImpact.s_cache.count = 0; - b2TimeOfImpact.s_distanceInput.useRadii = false; - for (;;) { - sweepA.GetTransform(b2TimeOfImpact.s_xfA, alpha); - sweepB.GetTransform(b2TimeOfImpact.s_xfB, alpha); - b2TimeOfImpact.s_distanceInput.proxyA = proxyA; - b2TimeOfImpact.s_distanceInput.proxyB = proxyB; - b2TimeOfImpact.s_distanceInput.transformA = b2TimeOfImpact.s_xfA; - b2TimeOfImpact.s_distanceInput.transformB = b2TimeOfImpact.s_xfB; - b2Distance.Distance(b2TimeOfImpact.s_distanceOutput, b2TimeOfImpact.s_cache, b2TimeOfImpact.s_distanceInput); - if (b2TimeOfImpact.s_distanceOutput.distance <= 0.0) { - alpha = 1.0; - break; - } - b2TimeOfImpact.s_fcn.Initialize(b2TimeOfImpact.s_cache, proxyA, b2TimeOfImpact.s_xfA, proxyB, b2TimeOfImpact.s_xfB); - var separation = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB); - if (separation <= 0.0) { - alpha = 1.0; - break; - } - if (iter == 0) { - if (separation > radius) { - target = b2Math.Max(radius - tolerance, 0.75 * radius); - } - else { - target = b2Math.Max(separation - tolerance, 0.02 * radius); - } - } - if (separation - target < 0.5 * tolerance) { - if (iter == 0) { - alpha = 1.0; - break; - } - break; - } - var newAlpha = alpha; { - var x1 = alpha; - var x2 = 1.0; - var f1 = separation; - sweepA.GetTransform(b2TimeOfImpact.s_xfA, x2); - sweepB.GetTransform(b2TimeOfImpact.s_xfB, x2); - var f2 = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB); - if (f2 >= target) { - alpha = 1.0; - break; - } - var rootIterCount = 0; - for (;;) { - var x = 0; - if (rootIterCount & 1) { - x = x1 + (target - f1) * (x2 - x1) / (f2 - f1); - } - else { - x = 0.5 * (x1 + x2); - } - sweepA.GetTransform(b2TimeOfImpact.s_xfA, x); - sweepB.GetTransform(b2TimeOfImpact.s_xfB, x); - var f = b2TimeOfImpact.s_fcn.Evaluate(b2TimeOfImpact.s_xfA, b2TimeOfImpact.s_xfB); - if (b2Math.Abs(f - target) < 0.025 * tolerance) { - newAlpha = x; - break; - } - if (f > target) { - x1 = x; - f1 = f; - } - else { - x2 = x; - f2 = f; - }++rootIterCount; - ++b2TimeOfImpact.b2_toiRootIters; - if (rootIterCount == 50) { - break; - } - } - b2TimeOfImpact.b2_toiMaxRootIters = b2Math.Max(b2TimeOfImpact.b2_toiMaxRootIters, rootIterCount); - } - if (newAlpha < (1.0 + 100.0 * Number.MIN_VALUE) * alpha) { - break; - } - alpha = newAlpha; - iter++; - ++b2TimeOfImpact.b2_toiIters; - if (iter == k_maxIterations) { - break; - } - } - b2TimeOfImpact.b2_toiMaxIters = b2Math.Max(b2TimeOfImpact.b2_toiMaxIters, iter); - return alpha; - } - Box2D.postDefs.push(function () { - Box2D.Collision.b2TimeOfImpact.b2_toiCalls = 0; - Box2D.Collision.b2TimeOfImpact.b2_toiIters = 0; - Box2D.Collision.b2TimeOfImpact.b2_toiMaxIters = 0; - Box2D.Collision.b2TimeOfImpact.b2_toiRootIters = 0; - Box2D.Collision.b2TimeOfImpact.b2_toiMaxRootIters = 0; - Box2D.Collision.b2TimeOfImpact.s_cache = new b2SimplexCache(); - Box2D.Collision.b2TimeOfImpact.s_distanceInput = new b2DistanceInput(); - Box2D.Collision.b2TimeOfImpact.s_xfA = new b2Transform(); - Box2D.Collision.b2TimeOfImpact.s_xfB = new b2Transform(); - Box2D.Collision.b2TimeOfImpact.s_fcn = new b2SeparationFunction(); - Box2D.Collision.b2TimeOfImpact.s_distanceOutput = new b2DistanceOutput(); - }); - b2TOIInput.b2TOIInput = function () { - this.proxyA = new b2DistanceProxy(); - this.proxyB = new b2DistanceProxy(); - this.sweepA = new b2Sweep(); - this.sweepB = new b2Sweep(); - }; - b2WorldManifold.b2WorldManifold = function () { - this.m_normal = new b2Vec2(); - }; - b2WorldManifold.prototype.b2WorldManifold = function () { - this.m_points = new Vector(b2Settings.b2_maxManifoldPoints); - for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { - this.m_points[i] = new b2Vec2(); - } - } - b2WorldManifold.prototype.Initialize = function (manifold, xfA, radiusA, xfB, radiusB) { - if (radiusA === undefined) radiusA = 0; - if (radiusB === undefined) radiusB = 0; - if (manifold.m_pointCount == 0) { - return; - } - var i = 0; - var tVec; - var tMat; - var normalX = 0; - var normalY = 0; - var planePointX = 0; - var planePointY = 0; - var clipPointX = 0; - var clipPointY = 0; - switch (manifold.m_type) { - case b2Manifold.e_circles: - { - tMat = xfA.R; - tVec = manifold.m_localPoint; - var pointAX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - var pointAY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = xfB.R; - tVec = manifold.m_points[0].m_localPoint; - var pointBX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - var pointBY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - var dX = pointBX - pointAX; - var dY = pointBY - pointAY; - var d2 = dX * dX + dY * dY; - if (d2 > Number.MIN_VALUE * Number.MIN_VALUE) { - var d = Math.sqrt(d2); - this.m_normal.x = dX / d; - this.m_normal.y = dY / d; - } - else { - this.m_normal.x = 1; - this.m_normal.y = 0; - } - var cAX = pointAX + radiusA * this.m_normal.x; - var cAY = pointAY + radiusA * this.m_normal.y; - var cBX = pointBX - radiusB * this.m_normal.x; - var cBY = pointBY - radiusB * this.m_normal.y; - this.m_points[0].x = 0.5 * (cAX + cBX); - this.m_points[0].y = 0.5 * (cAY + cBY); - } - break; - case b2Manifold.e_faceA: - { - tMat = xfA.R; - tVec = manifold.m_localPlaneNormal; - normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = xfA.R; - tVec = manifold.m_localPoint; - planePointX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - planePointY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - this.m_normal.x = normalX; - this.m_normal.y = normalY; - for (i = 0; - i < manifold.m_pointCount; i++) { - tMat = xfB.R; - tVec = manifold.m_points[i].m_localPoint; - clipPointX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - clipPointY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - this.m_points[i].x = clipPointX + 0.5 * (radiusA - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusB) * normalX; - this.m_points[i].y = clipPointY + 0.5 * (radiusA - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusB) * normalY; - } - } - break; - case b2Manifold.e_faceB: - { - tMat = xfB.R; - tVec = manifold.m_localPlaneNormal; - normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = xfB.R; - tVec = manifold.m_localPoint; - planePointX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - planePointY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - this.m_normal.x = (-normalX); - this.m_normal.y = (-normalY); - for (i = 0; - i < manifold.m_pointCount; i++) { - tMat = xfA.R; - tVec = manifold.m_points[i].m_localPoint; - clipPointX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - clipPointY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - this.m_points[i].x = clipPointX + 0.5 * (radiusB - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusA) * normalX; - this.m_points[i].y = clipPointY + 0.5 * (radiusB - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusA) * normalY; - } - } - break; - } - } - ClipVertex.ClipVertex = function () { - this.v = new b2Vec2(); - this.id = new b2ContactID(); - }; - ClipVertex.prototype.Set = function (other) { - this.v.SetV(other.v); - this.id.Set(other.id); - } - Features.Features = function () {}; - Object.defineProperty(Features.prototype, 'referenceEdge', { - enumerable: false, - configurable: true, - get: function () { - return this._referenceEdge; - } - }); - Object.defineProperty(Features.prototype, 'referenceEdge', { - enumerable: false, - configurable: true, - set: function (value) { - if (value === undefined) value = 0; - this._referenceEdge = value; - this._m_id._key = (this._m_id._key & 0xffffff00) | (this._referenceEdge & 0x000000ff); - } - }); - Object.defineProperty(Features.prototype, 'incidentEdge', { - enumerable: false, - configurable: true, - get: function () { - return this._incidentEdge; - } - }); - Object.defineProperty(Features.prototype, 'incidentEdge', { - enumerable: false, - configurable: true, - set: function (value) { - if (value === undefined) value = 0; - this._incidentEdge = value; - this._m_id._key = (this._m_id._key & 0xffff00ff) | ((this._incidentEdge << 8) & 0x0000ff00); - } - }); - Object.defineProperty(Features.prototype, 'incidentVertex', { - enumerable: false, - configurable: true, - get: function () { - return this._incidentVertex; - } - }); - Object.defineProperty(Features.prototype, 'incidentVertex', { - enumerable: false, - configurable: true, - set: function (value) { - if (value === undefined) value = 0; - this._incidentVertex = value; - this._m_id._key = (this._m_id._key & 0xff00ffff) | ((this._incidentVertex << 16) & 0x00ff0000); - } - }); - Object.defineProperty(Features.prototype, 'flip', { - enumerable: false, - configurable: true, - get: function () { - return this._flip; - } - }); - Object.defineProperty(Features.prototype, 'flip', { - enumerable: false, - configurable: true, - set: function (value) { - if (value === undefined) value = 0; - this._flip = value; - this._m_id._key = (this._m_id._key & 0x00ffffff) | ((this._flip << 24) & 0xff000000); - } - }); -})(); -(function () { - var b2Color = Box2D.Common.b2Color, - b2internal = Box2D.Common.b2internal, - b2Settings = Box2D.Common.b2Settings, - b2CircleShape = Box2D.Collision.Shapes.b2CircleShape, - b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef, - b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape, - b2MassData = Box2D.Collision.Shapes.b2MassData, - b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape, - b2Shape = Box2D.Collision.Shapes.b2Shape, - b2Mat22 = Box2D.Common.Math.b2Mat22, - b2Mat33 = Box2D.Common.Math.b2Mat33, - b2Math = Box2D.Common.Math.b2Math, - b2Sweep = Box2D.Common.Math.b2Sweep, - b2Transform = Box2D.Common.Math.b2Transform, - b2Vec2 = Box2D.Common.Math.b2Vec2, - b2Vec3 = Box2D.Common.Math.b2Vec3, - b2Body = Box2D.Dynamics.b2Body, - b2BodyDef = Box2D.Dynamics.b2BodyDef, - b2ContactFilter = Box2D.Dynamics.b2ContactFilter, - b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse, - b2ContactListener = Box2D.Dynamics.b2ContactListener, - b2ContactManager = Box2D.Dynamics.b2ContactManager, - b2DebugDraw = Box2D.Dynamics.b2DebugDraw, - b2DestructionListener = Box2D.Dynamics.b2DestructionListener, - b2FilterData = Box2D.Dynamics.b2FilterData, - b2Fixture = Box2D.Dynamics.b2Fixture, - b2FixtureDef = Box2D.Dynamics.b2FixtureDef, - b2Island = Box2D.Dynamics.b2Island, - b2TimeStep = Box2D.Dynamics.b2TimeStep, - b2World = Box2D.Dynamics.b2World, - b2AABB = Box2D.Collision.b2AABB, - b2Bound = Box2D.Collision.b2Bound, - b2BoundValues = Box2D.Collision.b2BoundValues, - b2Collision = Box2D.Collision.b2Collision, - b2ContactID = Box2D.Collision.b2ContactID, - b2ContactPoint = Box2D.Collision.b2ContactPoint, - b2Distance = Box2D.Collision.b2Distance, - b2DistanceInput = Box2D.Collision.b2DistanceInput, - b2DistanceOutput = Box2D.Collision.b2DistanceOutput, - b2DistanceProxy = Box2D.Collision.b2DistanceProxy, - b2DynamicTree = Box2D.Collision.b2DynamicTree, - b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase, - b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode, - b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair, - b2Manifold = Box2D.Collision.b2Manifold, - b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint, - b2Point = Box2D.Collision.b2Point, - b2RayCastInput = Box2D.Collision.b2RayCastInput, - b2RayCastOutput = Box2D.Collision.b2RayCastOutput, - b2Segment = Box2D.Collision.b2Segment, - b2SeparationFunction = Box2D.Collision.b2SeparationFunction, - b2Simplex = Box2D.Collision.b2Simplex, - b2SimplexCache = Box2D.Collision.b2SimplexCache, - b2SimplexVertex = Box2D.Collision.b2SimplexVertex, - b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact, - b2TOIInput = Box2D.Collision.b2TOIInput, - b2WorldManifold = Box2D.Collision.b2WorldManifold, - ClipVertex = Box2D.Collision.ClipVertex, - Features = Box2D.Collision.Features, - IBroadPhase = Box2D.Collision.IBroadPhase; - - Box2D.inherit(b2CircleShape, Box2D.Collision.Shapes.b2Shape); - b2CircleShape.prototype.__super = Box2D.Collision.Shapes.b2Shape.prototype; - b2CircleShape.b2CircleShape = function () { - Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this, arguments); - this.m_p = new b2Vec2(); - }; - b2CircleShape.prototype.Copy = function () { - var s = new b2CircleShape(); - s.Set(this); - return s; - } - b2CircleShape.prototype.Set = function (other) { - this.__super.Set.call(this, other); - if (Box2D.is(other, b2CircleShape)) { - var other2 = (other instanceof b2CircleShape ? other : null); - this.m_p.SetV(other2.m_p); - } - } - b2CircleShape.prototype.TestPoint = function (transform, p) { - var tMat = transform.R; - var dX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y); - var dY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y); - dX = p.x - dX; - dY = p.y - dY; - return (dX * dX + dY * dY) <= this.m_radius * this.m_radius; - } - b2CircleShape.prototype.RayCast = function (output, input, transform) { - var tMat = transform.R; - var positionX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y); - var positionY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y); - var sX = input.p1.x - positionX; - var sY = input.p1.y - positionY; - var b = (sX * sX + sY * sY) - this.m_radius * this.m_radius; - var rX = input.p2.x - input.p1.x; - var rY = input.p2.y - input.p1.y; - var c = (sX * rX + sY * rY); - var rr = (rX * rX + rY * rY); - var sigma = c * c - rr * b; - if (sigma < 0.0 || rr < Number.MIN_VALUE) { - return false; - } - var a = (-(c + Math.sqrt(sigma))); - if (0.0 <= a && a <= input.maxFraction * rr) { - a /= rr; - output.fraction = a; - output.normal.x = sX + a * rX; - output.normal.y = sY + a * rY; - output.normal.Normalize(); - return true; - } - return false; - } - b2CircleShape.prototype.ComputeAABB = function (aabb, transform) { - var tMat = transform.R; - var pX = transform.position.x + (tMat.col1.x * this.m_p.x + tMat.col2.x * this.m_p.y); - var pY = transform.position.y + (tMat.col1.y * this.m_p.x + tMat.col2.y * this.m_p.y); - aabb.lowerBound.Set(pX - this.m_radius, pY - this.m_radius); - aabb.upperBound.Set(pX + this.m_radius, pY + this.m_radius); - } - b2CircleShape.prototype.ComputeMass = function (massData, density) { - if (density === undefined) density = 0; - massData.mass = density * b2Settings.b2_pi * this.m_radius * this.m_radius; - massData.center.SetV(this.m_p); - massData.I = massData.mass * (0.5 * this.m_radius * this.m_radius + (this.m_p.x * this.m_p.x + this.m_p.y * this.m_p.y)); - } - b2CircleShape.prototype.ComputeSubmergedArea = function (normal, offset, xf, c) { - if (offset === undefined) offset = 0; - var p = b2Math.MulX(xf, this.m_p); - var l = (-(b2Math.Dot(normal, p) - offset)); - if (l < (-this.m_radius) + Number.MIN_VALUE) { - return 0; - } - if (l > this.m_radius) { - c.SetV(p); - return Math.PI * this.m_radius * this.m_radius; - } - var r2 = this.m_radius * this.m_radius; - var l2 = l * l; - var area = r2 * (Math.asin(l / this.m_radius) + Math.PI / 2) + l * Math.sqrt(r2 - l2); - var com = (-2 / 3 * Math.pow(r2 - l2, 1.5) / area); - c.x = p.x + normal.x * com; - c.y = p.y + normal.y * com; - return area; - } - b2CircleShape.prototype.GetLocalPosition = function () { - return this.m_p; - } - b2CircleShape.prototype.SetLocalPosition = function (position) { - this.m_p.SetV(position); - } - b2CircleShape.prototype.GetRadius = function () { - return this.m_radius; - } - b2CircleShape.prototype.SetRadius = function (radius) { - if (radius === undefined) radius = 0; - this.m_radius = radius; - } - b2CircleShape.prototype.b2CircleShape = function (radius) { - if (radius === undefined) radius = 0; - this.__super.b2Shape.call(this); - this.m_type = b2Shape.e_circleShape; - this.m_radius = radius; - } - b2EdgeChainDef.b2EdgeChainDef = function () {}; - b2EdgeChainDef.prototype.b2EdgeChainDef = function () { - this.vertexCount = 0; - this.isALoop = true; - this.vertices = []; - } - Box2D.inherit(b2EdgeShape, Box2D.Collision.Shapes.b2Shape); - b2EdgeShape.prototype.__super = Box2D.Collision.Shapes.b2Shape.prototype; - b2EdgeShape.b2EdgeShape = function () { - Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this, arguments); - this.s_supportVec = new b2Vec2(); - this.m_v1 = new b2Vec2(); - this.m_v2 = new b2Vec2(); - this.m_coreV1 = new b2Vec2(); - this.m_coreV2 = new b2Vec2(); - this.m_normal = new b2Vec2(); - this.m_direction = new b2Vec2(); - this.m_cornerDir1 = new b2Vec2(); - this.m_cornerDir2 = new b2Vec2(); - }; - b2EdgeShape.prototype.TestPoint = function (transform, p) { - return false; - } - b2EdgeShape.prototype.RayCast = function (output, input, transform) { - var tMat; - var rX = input.p2.x - input.p1.x; - var rY = input.p2.y - input.p1.y; - tMat = transform.R; - var v1X = transform.position.x + (tMat.col1.x * this.m_v1.x + tMat.col2.x * this.m_v1.y); - var v1Y = transform.position.y + (tMat.col1.y * this.m_v1.x + tMat.col2.y * this.m_v1.y); - var nX = transform.position.y + (tMat.col1.y * this.m_v2.x + tMat.col2.y * this.m_v2.y) - v1Y; - var nY = (-(transform.position.x + (tMat.col1.x * this.m_v2.x + tMat.col2.x * this.m_v2.y) - v1X)); - var k_slop = 100.0 * Number.MIN_VALUE; - var denom = (-(rX * nX + rY * nY)); - if (denom > k_slop) { - var bX = input.p1.x - v1X; - var bY = input.p1.y - v1Y; - var a = (bX * nX + bY * nY); - if (0.0 <= a && a <= input.maxFraction * denom) { - var mu2 = (-rX * bY) + rY * bX; - if ((-k_slop * denom) <= mu2 && mu2 <= denom * (1.0 + k_slop)) { - a /= denom; - output.fraction = a; - var nLen = Math.sqrt(nX * nX + nY * nY); - output.normal.x = nX / nLen; - output.normal.y = nY / nLen; - return true; - } - } - } - return false; - } - b2EdgeShape.prototype.ComputeAABB = function (aabb, transform) { - var tMat = transform.R; - var v1X = transform.position.x + (tMat.col1.x * this.m_v1.x + tMat.col2.x * this.m_v1.y); - var v1Y = transform.position.y + (tMat.col1.y * this.m_v1.x + tMat.col2.y * this.m_v1.y); - var v2X = transform.position.x + (tMat.col1.x * this.m_v2.x + tMat.col2.x * this.m_v2.y); - var v2Y = transform.position.y + (tMat.col1.y * this.m_v2.x + tMat.col2.y * this.m_v2.y); - if (v1X < v2X) { - aabb.lowerBound.x = v1X; - aabb.upperBound.x = v2X; - } - else { - aabb.lowerBound.x = v2X; - aabb.upperBound.x = v1X; - } - if (v1Y < v2Y) { - aabb.lowerBound.y = v1Y; - aabb.upperBound.y = v2Y; - } - else { - aabb.lowerBound.y = v2Y; - aabb.upperBound.y = v1Y; - } - } - b2EdgeShape.prototype.ComputeMass = function (massData, density) { - if (density === undefined) density = 0; - massData.mass = 0; - massData.center.SetV(this.m_v1); - massData.I = 0; - } - b2EdgeShape.prototype.ComputeSubmergedArea = function (normal, offset, xf, c) { - if (offset === undefined) offset = 0; - var v0 = new b2Vec2(normal.x * offset, normal.y * offset); - var v1 = b2Math.MulX(xf, this.m_v1); - var v2 = b2Math.MulX(xf, this.m_v2); - var d1 = b2Math.Dot(normal, v1) - offset; - var d2 = b2Math.Dot(normal, v2) - offset; - if (d1 > 0) { - if (d2 > 0) { - return 0; - } - else { - v1.x = (-d2 / (d1 - d2) * v1.x) + d1 / (d1 - d2) * v2.x; - v1.y = (-d2 / (d1 - d2) * v1.y) + d1 / (d1 - d2) * v2.y; - } - } - else { - if (d2 > 0) { - v2.x = (-d2 / (d1 - d2) * v1.x) + d1 / (d1 - d2) * v2.x; - v2.y = (-d2 / (d1 - d2) * v1.y) + d1 / (d1 - d2) * v2.y; - } - else {} - } - c.x = (v0.x + v1.x + v2.x) / 3; - c.y = (v0.y + v1.y + v2.y) / 3; - return 0.5 * ((v1.x - v0.x) * (v2.y - v0.y) - (v1.y - v0.y) * (v2.x - v0.x)); - } - b2EdgeShape.prototype.GetLength = function () { - return this.m_length; - } - b2EdgeShape.prototype.GetVertex1 = function () { - return this.m_v1; - } - b2EdgeShape.prototype.GetVertex2 = function () { - return this.m_v2; - } - b2EdgeShape.prototype.GetCoreVertex1 = function () { - return this.m_coreV1; - } - b2EdgeShape.prototype.GetCoreVertex2 = function () { - return this.m_coreV2; - } - b2EdgeShape.prototype.GetNormalVector = function () { - return this.m_normal; - } - b2EdgeShape.prototype.GetDirectionVector = function () { - return this.m_direction; - } - b2EdgeShape.prototype.GetCorner1Vector = function () { - return this.m_cornerDir1; - } - b2EdgeShape.prototype.GetCorner2Vector = function () { - return this.m_cornerDir2; - } - b2EdgeShape.prototype.Corner1IsConvex = function () { - return this.m_cornerConvex1; - } - b2EdgeShape.prototype.Corner2IsConvex = function () { - return this.m_cornerConvex2; - } - b2EdgeShape.prototype.GetFirstVertex = function (xf) { - var tMat = xf.R; - return new b2Vec2(xf.position.x + (tMat.col1.x * this.m_coreV1.x + tMat.col2.x * this.m_coreV1.y), xf.position.y + (tMat.col1.y * this.m_coreV1.x + tMat.col2.y * this.m_coreV1.y)); - } - b2EdgeShape.prototype.GetNextEdge = function () { - return this.m_nextEdge; - } - b2EdgeShape.prototype.GetPrevEdge = function () { - return this.m_prevEdge; - } - b2EdgeShape.prototype.Support = function (xf, dX, dY) { - if (dX === undefined) dX = 0; - if (dY === undefined) dY = 0; - var tMat = xf.R; - var v1X = xf.position.x + (tMat.col1.x * this.m_coreV1.x + tMat.col2.x * this.m_coreV1.y); - var v1Y = xf.position.y + (tMat.col1.y * this.m_coreV1.x + tMat.col2.y * this.m_coreV1.y); - var v2X = xf.position.x + (tMat.col1.x * this.m_coreV2.x + tMat.col2.x * this.m_coreV2.y); - var v2Y = xf.position.y + (tMat.col1.y * this.m_coreV2.x + tMat.col2.y * this.m_coreV2.y); - if ((v1X * dX + v1Y * dY) > (v2X * dX + v2Y * dY)) { - this.s_supportVec.x = v1X; - this.s_supportVec.y = v1Y; - } - else { - this.s_supportVec.x = v2X; - this.s_supportVec.y = v2Y; - } - return this.s_supportVec; - } - b2EdgeShape.prototype.b2EdgeShape = function (v1, v2) { - this.__super.b2Shape.call(this); - this.m_type = b2Shape.e_edgeShape; - this.m_prevEdge = null; - this.m_nextEdge = null; - this.m_v1 = v1; - this.m_v2 = v2; - this.m_direction.Set(this.m_v2.x - this.m_v1.x, this.m_v2.y - this.m_v1.y); - this.m_length = this.m_direction.Normalize(); - this.m_normal.Set(this.m_direction.y, (-this.m_direction.x)); - this.m_coreV1.Set((-b2Settings.b2_toiSlop * (this.m_normal.x - this.m_direction.x)) + this.m_v1.x, (-b2Settings.b2_toiSlop * (this.m_normal.y - this.m_direction.y)) + this.m_v1.y); - this.m_coreV2.Set((-b2Settings.b2_toiSlop * (this.m_normal.x + this.m_direction.x)) + this.m_v2.x, (-b2Settings.b2_toiSlop * (this.m_normal.y + this.m_direction.y)) + this.m_v2.y); - this.m_cornerDir1 = this.m_normal; - this.m_cornerDir2.Set((-this.m_normal.x), (-this.m_normal.y)); - } - b2EdgeShape.prototype.SetPrevEdge = function (edge, core, cornerDir, convex) { - this.m_prevEdge = edge; - this.m_coreV1 = core; - this.m_cornerDir1 = cornerDir; - this.m_cornerConvex1 = convex; - } - b2EdgeShape.prototype.SetNextEdge = function (edge, core, cornerDir, convex) { - this.m_nextEdge = edge; - this.m_coreV2 = core; - this.m_cornerDir2 = cornerDir; - this.m_cornerConvex2 = convex; - } - b2MassData.b2MassData = function () { - this.mass = 0.0; - this.center = new b2Vec2(0, 0); - this.I = 0.0; - }; - Box2D.inherit(b2PolygonShape, Box2D.Collision.Shapes.b2Shape); - b2PolygonShape.prototype.__super = Box2D.Collision.Shapes.b2Shape.prototype; - b2PolygonShape.b2PolygonShape = function () { - Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this, arguments); - }; - b2PolygonShape.prototype.Copy = function () { - var s = new b2PolygonShape(); - s.Set(this); - return s; - } - b2PolygonShape.prototype.Set = function (other) { - this.__super.Set.call(this, other); - if (Box2D.is(other, b2PolygonShape)) { - var other2 = (other instanceof b2PolygonShape ? other : null); - this.m_centroid.SetV(other2.m_centroid); - this.m_vertexCount = other2.m_vertexCount; - this.Reserve(this.m_vertexCount); - for (var i = 0; i < this.m_vertexCount; i++) { - this.m_vertices[i].SetV(other2.m_vertices[i]); - this.m_normals[i].SetV(other2.m_normals[i]); - } - } - } - b2PolygonShape.prototype.SetAsArray = function (vertices, vertexCount) { - if (vertexCount === undefined) vertexCount = 0; - var v = new Vector(); - var i = 0, - tVec; - for (i = 0; - i < vertices.length; ++i) { - tVec = vertices[i]; - v.push(tVec); - } - this.SetAsVector(v, vertexCount); - } - b2PolygonShape.AsArray = function (vertices, vertexCount) { - if (vertexCount === undefined) vertexCount = 0; - var polygonShape = new b2PolygonShape(); - polygonShape.SetAsArray(vertices, vertexCount); - return polygonShape; - } - b2PolygonShape.prototype.SetAsVector = function (vertices, vertexCount) { - if (vertexCount === undefined) vertexCount = 0; - if (vertexCount == 0) vertexCount = vertices.length; - b2Settings.b2Assert(2 <= vertexCount); - this.m_vertexCount = vertexCount; - this.Reserve(vertexCount); - var i = 0; - for (i = 0; - i < this.m_vertexCount; i++) { - this.m_vertices[i].SetV(vertices[i]); - } - for (i = 0; - i < this.m_vertexCount; ++i) { - var i1 = parseInt(i); - var i2 = parseInt(i + 1 < this.m_vertexCount ? i + 1 : 0); - var edge = b2Math.SubtractVV(this.m_vertices[i2], this.m_vertices[i1]); - b2Settings.b2Assert(edge.LengthSquared() > Number.MIN_VALUE); - this.m_normals[i].SetV(b2Math.CrossVF(edge, 1.0)); - this.m_normals[i].Normalize(); - } - this.m_centroid = b2PolygonShape.ComputeCentroid(this.m_vertices, this.m_vertexCount); - } - b2PolygonShape.AsVector = function (vertices, vertexCount) { - if (vertexCount === undefined) vertexCount = 0; - var polygonShape = new b2PolygonShape(); - polygonShape.SetAsVector(vertices, vertexCount); - return polygonShape; - } - b2PolygonShape.prototype.SetAsBox = function (hx, hy) { - if (hx === undefined) hx = 0; - if (hy === undefined) hy = 0; - this.m_vertexCount = 4; - this.Reserve(4); - this.m_vertices[0].Set((-hx), (-hy)); - this.m_vertices[1].Set(hx, (-hy)); - this.m_vertices[2].Set(hx, hy); - this.m_vertices[3].Set((-hx), hy); - this.m_normals[0].Set(0.0, (-1.0)); - this.m_normals[1].Set(1.0, 0.0); - this.m_normals[2].Set(0.0, 1.0); - this.m_normals[3].Set((-1.0), 0.0); - this.m_centroid.SetZero(); - } - b2PolygonShape.AsBox = function (hx, hy) { - if (hx === undefined) hx = 0; - if (hy === undefined) hy = 0; - var polygonShape = new b2PolygonShape(); - polygonShape.SetAsBox(hx, hy); - return polygonShape; - } - b2PolygonShape.prototype.SetAsOrientedBox = function (hx, hy, center, angle) { - if (hx === undefined) hx = 0; - if (hy === undefined) hy = 0; - if (center === undefined) center = null; - if (angle === undefined) angle = 0.0; - this.m_vertexCount = 4; - this.Reserve(4); - this.m_vertices[0].Set((-hx), (-hy)); - this.m_vertices[1].Set(hx, (-hy)); - this.m_vertices[2].Set(hx, hy); - this.m_vertices[3].Set((-hx), hy); - this.m_normals[0].Set(0.0, (-1.0)); - this.m_normals[1].Set(1.0, 0.0); - this.m_normals[2].Set(0.0, 1.0); - this.m_normals[3].Set((-1.0), 0.0); - this.m_centroid = center; - var xf = new b2Transform(); - xf.position = center; - xf.R.Set(angle); - for (var i = 0; i < this.m_vertexCount; ++i) { - this.m_vertices[i] = b2Math.MulX(xf, this.m_vertices[i]); - this.m_normals[i] = b2Math.MulMV(xf.R, this.m_normals[i]); - } - } - b2PolygonShape.AsOrientedBox = function (hx, hy, center, angle) { - if (hx === undefined) hx = 0; - if (hy === undefined) hy = 0; - if (center === undefined) center = null; - if (angle === undefined) angle = 0.0; - var polygonShape = new b2PolygonShape(); - polygonShape.SetAsOrientedBox(hx, hy, center, angle); - return polygonShape; - } - b2PolygonShape.prototype.SetAsEdge = function (v1, v2) { - this.m_vertexCount = 2; - this.Reserve(2); - this.m_vertices[0].SetV(v1); - this.m_vertices[1].SetV(v2); - this.m_centroid.x = 0.5 * (v1.x + v2.x); - this.m_centroid.y = 0.5 * (v1.y + v2.y); - this.m_normals[0] = b2Math.CrossVF(b2Math.SubtractVV(v2, v1), 1.0); - this.m_normals[0].Normalize(); - this.m_normals[1].x = (-this.m_normals[0].x); - this.m_normals[1].y = (-this.m_normals[0].y); - } - b2PolygonShape.AsEdge = function (v1, v2) { - var polygonShape = new b2PolygonShape(); - polygonShape.SetAsEdge(v1, v2); - return polygonShape; - } - b2PolygonShape.prototype.TestPoint = function (xf, p) { - var tVec; - var tMat = xf.R; - var tX = p.x - xf.position.x; - var tY = p.y - xf.position.y; - var pLocalX = (tX * tMat.col1.x + tY * tMat.col1.y); - var pLocalY = (tX * tMat.col2.x + tY * tMat.col2.y); - for (var i = 0; i < this.m_vertexCount; ++i) { - tVec = this.m_vertices[i]; - tX = pLocalX - tVec.x; - tY = pLocalY - tVec.y; - tVec = this.m_normals[i]; - var dot = (tVec.x * tX + tVec.y * tY); - if (dot > 0.0) { - return false; - } - } - return true; - } - b2PolygonShape.prototype.RayCast = function (output, input, transform) { - var lower = 0.0; - var upper = input.maxFraction; - var tX = 0; - var tY = 0; - var tMat; - var tVec; - tX = input.p1.x - transform.position.x; - tY = input.p1.y - transform.position.y; - tMat = transform.R; - var p1X = (tX * tMat.col1.x + tY * tMat.col1.y); - var p1Y = (tX * tMat.col2.x + tY * tMat.col2.y); - tX = input.p2.x - transform.position.x; - tY = input.p2.y - transform.position.y; - tMat = transform.R; - var p2X = (tX * tMat.col1.x + tY * tMat.col1.y); - var p2Y = (tX * tMat.col2.x + tY * tMat.col2.y); - var dX = p2X - p1X; - var dY = p2Y - p1Y; - var index = parseInt((-1)); - for (var i = 0; i < this.m_vertexCount; ++i) { - tVec = this.m_vertices[i]; - tX = tVec.x - p1X; - tY = tVec.y - p1Y; - tVec = this.m_normals[i]; - var numerator = (tVec.x * tX + tVec.y * tY); - var denominator = (tVec.x * dX + tVec.y * dY); - if (denominator == 0.0) { - if (numerator < 0.0) { - return false; - } - } - else { - if (denominator < 0.0 && numerator < lower * denominator) { - lower = numerator / denominator; - index = i; - } - else if (denominator > 0.0 && numerator < upper * denominator) { - upper = numerator / denominator; - } - } - if (upper < lower - Number.MIN_VALUE) { - return false; - } - } - if (index >= 0) { - output.fraction = lower; - tMat = transform.R; - tVec = this.m_normals[index]; - output.normal.x = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - output.normal.y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - return true; - } - return false; - } - b2PolygonShape.prototype.ComputeAABB = function (aabb, xf) { - var tMat = xf.R; - var tVec = this.m_vertices[0]; - var lowerX = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var lowerY = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - var upperX = lowerX; - var upperY = lowerY; - for (var i = 1; i < this.m_vertexCount; ++i) { - tVec = this.m_vertices[i]; - var vX = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var vY = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - lowerX = lowerX < vX ? lowerX : vX; - lowerY = lowerY < vY ? lowerY : vY; - upperX = upperX > vX ? upperX : vX; - upperY = upperY > vY ? upperY : vY; - } - aabb.lowerBound.x = lowerX - this.m_radius; - aabb.lowerBound.y = lowerY - this.m_radius; - aabb.upperBound.x = upperX + this.m_radius; - aabb.upperBound.y = upperY + this.m_radius; - } - b2PolygonShape.prototype.ComputeMass = function (massData, density) { - if (density === undefined) density = 0; - if (this.m_vertexCount == 2) { - massData.center.x = 0.5 * (this.m_vertices[0].x + this.m_vertices[1].x); - massData.center.y = 0.5 * (this.m_vertices[0].y + this.m_vertices[1].y); - massData.mass = 0.0; - massData.I = 0.0; - return; - } - var centerX = 0.0; - var centerY = 0.0; - var area = 0.0; - var I = 0.0; - var p1X = 0.0; - var p1Y = 0.0; - var k_inv3 = 1.0 / 3.0; - for (var i = 0; i < this.m_vertexCount; ++i) { - var p2 = this.m_vertices[i]; - var p3 = i + 1 < this.m_vertexCount ? this.m_vertices[parseInt(i + 1)] : this.m_vertices[0]; - var e1X = p2.x - p1X; - var e1Y = p2.y - p1Y; - var e2X = p3.x - p1X; - var e2Y = p3.y - p1Y; - var D = e1X * e2Y - e1Y * e2X; - var triangleArea = 0.5 * D;area += triangleArea; - centerX += triangleArea * k_inv3 * (p1X + p2.x + p3.x); - centerY += triangleArea * k_inv3 * (p1Y + p2.y + p3.y); - var px = p1X; - var py = p1Y; - var ex1 = e1X; - var ey1 = e1Y; - var ex2 = e2X; - var ey2 = e2Y; - var intx2 = k_inv3 * (0.25 * (ex1 * ex1 + ex2 * ex1 + ex2 * ex2) + (px * ex1 + px * ex2)) + 0.5 * px * px; - var inty2 = k_inv3 * (0.25 * (ey1 * ey1 + ey2 * ey1 + ey2 * ey2) + (py * ey1 + py * ey2)) + 0.5 * py * py;I += D * (intx2 + inty2); - } - massData.mass = density * area; - centerX *= 1.0 / area; - centerY *= 1.0 / area; - massData.center.Set(centerX, centerY); - massData.I = density * I; - } - b2PolygonShape.prototype.ComputeSubmergedArea = function (normal, offset, xf, c) { - if (offset === undefined) offset = 0; - var normalL = b2Math.MulTMV(xf.R, normal); - var offsetL = offset - b2Math.Dot(normal, xf.position); - var depths = new Vector_a2j_Number(); - var diveCount = 0; - var intoIndex = parseInt((-1)); - var outoIndex = parseInt((-1)); - var lastSubmerged = false; - var i = 0; - for (i = 0; - i < this.m_vertexCount; ++i) { - depths[i] = b2Math.Dot(normalL, this.m_vertices[i]) - offsetL; - var isSubmerged = depths[i] < (-Number.MIN_VALUE); - if (i > 0) { - if (isSubmerged) { - if (!lastSubmerged) { - intoIndex = i - 1; - diveCount++; - } - } - else { - if (lastSubmerged) { - outoIndex = i - 1; - diveCount++; - } - } - } - lastSubmerged = isSubmerged; - } - switch (diveCount) { - case 0: - if (lastSubmerged) { - var md = new b2MassData(); - this.ComputeMass(md, 1); - c.SetV(b2Math.MulX(xf, md.center)); - return md.mass; - } - else { - return 0; - } - break; - case 1: - if (intoIndex == (-1)) { - intoIndex = this.m_vertexCount - 1; - } - else { - outoIndex = this.m_vertexCount - 1; - } - break; - } - var intoIndex2 = parseInt((intoIndex + 1) % this.m_vertexCount); - var outoIndex2 = parseInt((outoIndex + 1) % this.m_vertexCount); - var intoLamdda = (0 - depths[intoIndex]) / (depths[intoIndex2] - depths[intoIndex]); - var outoLamdda = (0 - depths[outoIndex]) / (depths[outoIndex2] - depths[outoIndex]); - var intoVec = new b2Vec2(this.m_vertices[intoIndex].x * (1 - intoLamdda) + this.m_vertices[intoIndex2].x * intoLamdda, this.m_vertices[intoIndex].y * (1 - intoLamdda) + this.m_vertices[intoIndex2].y * intoLamdda); - var outoVec = new b2Vec2(this.m_vertices[outoIndex].x * (1 - outoLamdda) + this.m_vertices[outoIndex2].x * outoLamdda, this.m_vertices[outoIndex].y * (1 - outoLamdda) + this.m_vertices[outoIndex2].y * outoLamdda); - var area = 0; - var center = new b2Vec2(); - var p2 = this.m_vertices[intoIndex2]; - var p3; - i = intoIndex2; - while (i != outoIndex2) { - i = (i + 1) % this.m_vertexCount; - if (i == outoIndex2) p3 = outoVec; - else p3 = this.m_vertices[i]; - var triangleArea = 0.5 * ((p2.x - intoVec.x) * (p3.y - intoVec.y) - (p2.y - intoVec.y) * (p3.x - intoVec.x)); - area += triangleArea; - center.x += triangleArea * (intoVec.x + p2.x + p3.x) / 3; - center.y += triangleArea * (intoVec.y + p2.y + p3.y) / 3; - p2 = p3; - } - center.Multiply(1 / area); - c.SetV(b2Math.MulX(xf, center)); - return area; - } - b2PolygonShape.prototype.GetVertexCount = function () { - return this.m_vertexCount; - } - b2PolygonShape.prototype.GetVertices = function () { - return this.m_vertices; - } - b2PolygonShape.prototype.GetNormals = function () { - return this.m_normals; - } - b2PolygonShape.prototype.GetSupport = function (d) { - var bestIndex = 0; - var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y; - for (var i = 1; i < this.m_vertexCount; ++i) { - var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y; - if (value > bestValue) { - bestIndex = i; - bestValue = value; - } - } - return bestIndex; - } - b2PolygonShape.prototype.GetSupportVertex = function (d) { - var bestIndex = 0; - var bestValue = this.m_vertices[0].x * d.x + this.m_vertices[0].y * d.y; - for (var i = 1; i < this.m_vertexCount; ++i) { - var value = this.m_vertices[i].x * d.x + this.m_vertices[i].y * d.y; - if (value > bestValue) { - bestIndex = i; - bestValue = value; - } - } - return this.m_vertices[bestIndex]; - } - b2PolygonShape.prototype.Validate = function () { - return false; - } - b2PolygonShape.prototype.b2PolygonShape = function () { - this.__super.b2Shape.call(this); - this.m_type = b2Shape.e_polygonShape; - this.m_centroid = new b2Vec2(); - this.m_vertices = new Vector(); - this.m_normals = new Vector(); - } - b2PolygonShape.prototype.Reserve = function (count) { - if (count === undefined) count = 0; - for (var i = parseInt(this.m_vertices.length); i < count; i++) { - this.m_vertices[i] = new b2Vec2(); - this.m_normals[i] = new b2Vec2(); - } - } - b2PolygonShape.ComputeCentroid = function (vs, count) { - if (count === undefined) count = 0; - var c = new b2Vec2(); - var area = 0.0; - var p1X = 0.0; - var p1Y = 0.0; - var inv3 = 1.0 / 3.0; - for (var i = 0; i < count; ++i) { - var p2 = vs[i]; - var p3 = i + 1 < count ? vs[parseInt(i + 1)] : vs[0]; - var e1X = p2.x - p1X; - var e1Y = p2.y - p1Y; - var e2X = p3.x - p1X; - var e2Y = p3.y - p1Y; - var D = (e1X * e2Y - e1Y * e2X); - var triangleArea = 0.5 * D;area += triangleArea; - c.x += triangleArea * inv3 * (p1X + p2.x + p3.x); - c.y += triangleArea * inv3 * (p1Y + p2.y + p3.y); - } - c.x *= 1.0 / area; - c.y *= 1.0 / area; - return c; - } - b2PolygonShape.ComputeOBB = function (obb, vs, count) { - if (count === undefined) count = 0; - var i = 0; - var p = new Vector(count + 1); - for (i = 0; - i < count; ++i) { - p[i] = vs[i]; - } - p[count] = p[0]; - var minArea = Number.MAX_VALUE; - for (i = 1; - i <= count; ++i) { - var root = p[parseInt(i - 1)]; - var uxX = p[i].x - root.x; - var uxY = p[i].y - root.y; - var length = Math.sqrt(uxX * uxX + uxY * uxY); - uxX /= length; - uxY /= length; - var uyX = (-uxY); - var uyY = uxX; - var lowerX = Number.MAX_VALUE; - var lowerY = Number.MAX_VALUE; - var upperX = (-Number.MAX_VALUE); - var upperY = (-Number.MAX_VALUE); - for (var j = 0; j < count; ++j) { - var dX = p[j].x - root.x; - var dY = p[j].y - root.y; - var rX = (uxX * dX + uxY * dY); - var rY = (uyX * dX + uyY * dY); - if (rX < lowerX) lowerX = rX; - if (rY < lowerY) lowerY = rY; - if (rX > upperX) upperX = rX; - if (rY > upperY) upperY = rY; - } - var area = (upperX - lowerX) * (upperY - lowerY); - if (area < 0.95 * minArea) { - minArea = area; - obb.R.col1.x = uxX; - obb.R.col1.y = uxY; - obb.R.col2.x = uyX; - obb.R.col2.y = uyY; - var centerX = 0.5 * (lowerX + upperX); - var centerY = 0.5 * (lowerY + upperY); - var tMat = obb.R; - obb.center.x = root.x + (tMat.col1.x * centerX + tMat.col2.x * centerY); - obb.center.y = root.y + (tMat.col1.y * centerX + tMat.col2.y * centerY); - obb.extents.x = 0.5 * (upperX - lowerX); - obb.extents.y = 0.5 * (upperY - lowerY); - } - } - } - Box2D.postDefs.push(function () { - Box2D.Collision.Shapes.b2PolygonShape.s_mat = new b2Mat22(); - }); - b2Shape.b2Shape = function () {}; - b2Shape.prototype.Copy = function () { - return null; - } - b2Shape.prototype.Set = function (other) { - this.m_radius = other.m_radius; - } - b2Shape.prototype.GetType = function () { - return this.m_type; - } - b2Shape.prototype.TestPoint = function (xf, p) { - return false; - } - b2Shape.prototype.RayCast = function (output, input, transform) { - return false; - } - b2Shape.prototype.ComputeAABB = function (aabb, xf) {} - b2Shape.prototype.ComputeMass = function (massData, density) { - if (density === undefined) density = 0; - } - b2Shape.prototype.ComputeSubmergedArea = function (normal, offset, xf, c) { - if (offset === undefined) offset = 0; - return 0; - } - b2Shape.TestOverlap = function (shape1, transform1, shape2, transform2) { - var input = new b2DistanceInput(); - input.proxyA = new b2DistanceProxy(); - input.proxyA.Set(shape1); - input.proxyB = new b2DistanceProxy(); - input.proxyB.Set(shape2); - input.transformA = transform1; - input.transformB = transform2; - input.useRadii = true; - var simplexCache = new b2SimplexCache(); - simplexCache.count = 0; - var output = new b2DistanceOutput(); - b2Distance.Distance(output, simplexCache, input); - return output.distance < 10.0 * Number.MIN_VALUE; - } - b2Shape.prototype.b2Shape = function () { - this.m_type = b2Shape.e_unknownShape; - this.m_radius = b2Settings.b2_linearSlop; - } - Box2D.postDefs.push(function () { - Box2D.Collision.Shapes.b2Shape.e_unknownShape = parseInt((-1)); - Box2D.Collision.Shapes.b2Shape.e_circleShape = 0; - Box2D.Collision.Shapes.b2Shape.e_polygonShape = 1; - Box2D.Collision.Shapes.b2Shape.e_edgeShape = 2; - Box2D.Collision.Shapes.b2Shape.e_shapeTypeCount = 3; - Box2D.Collision.Shapes.b2Shape.e_hitCollide = 1; - Box2D.Collision.Shapes.b2Shape.e_missCollide = 0; - Box2D.Collision.Shapes.b2Shape.e_startsInsideCollide = parseInt((-1)); - }); -})(); -(function () { - var b2Color = Box2D.Common.b2Color, - b2internal = Box2D.Common.b2internal, - b2Settings = Box2D.Common.b2Settings, - b2Mat22 = Box2D.Common.Math.b2Mat22, - b2Mat33 = Box2D.Common.Math.b2Mat33, - b2Math = Box2D.Common.Math.b2Math, - b2Sweep = Box2D.Common.Math.b2Sweep, - b2Transform = Box2D.Common.Math.b2Transform, - b2Vec2 = Box2D.Common.Math.b2Vec2, - b2Vec3 = Box2D.Common.Math.b2Vec3; - - b2Color.b2Color = function () { - this._r = 0; - this._g = 0; - this._b = 0; - }; - b2Color.prototype.b2Color = function (rr, gg, bb) { - if (rr === undefined) rr = 0; - if (gg === undefined) gg = 0; - if (bb === undefined) bb = 0; - this._r = Box2D.parseUInt(255 * b2Math.Clamp(rr, 0.0, 1.0)); - this._g = Box2D.parseUInt(255 * b2Math.Clamp(gg, 0.0, 1.0)); - this._b = Box2D.parseUInt(255 * b2Math.Clamp(bb, 0.0, 1.0)); - } - b2Color.prototype.Set = function (rr, gg, bb) { - if (rr === undefined) rr = 0; - if (gg === undefined) gg = 0; - if (bb === undefined) bb = 0; - this._r = Box2D.parseUInt(255 * b2Math.Clamp(rr, 0.0, 1.0)); - this._g = Box2D.parseUInt(255 * b2Math.Clamp(gg, 0.0, 1.0)); - this._b = Box2D.parseUInt(255 * b2Math.Clamp(bb, 0.0, 1.0)); - } - Object.defineProperty(b2Color.prototype, 'r', { - enumerable: false, - configurable: true, - set: function (rr) { - if (rr === undefined) rr = 0; - this._r = Box2D.parseUInt(255 * b2Math.Clamp(rr, 0.0, 1.0)); - } - }); - Object.defineProperty(b2Color.prototype, 'g', { - enumerable: false, - configurable: true, - set: function (gg) { - if (gg === undefined) gg = 0; - this._g = Box2D.parseUInt(255 * b2Math.Clamp(gg, 0.0, 1.0)); - } - }); - Object.defineProperty(b2Color.prototype, 'b', { - enumerable: false, - configurable: true, - set: function (bb) { - if (bb === undefined) bb = 0; - this._b = Box2D.parseUInt(255 * b2Math.Clamp(bb, 0.0, 1.0)); - } - }); - Object.defineProperty(b2Color.prototype, 'color', { - enumerable: false, - configurable: true, - get: function () { - return (this._r << 16) | (this._g << 8) | (this._b); - } - }); - b2Settings.b2Settings = function () {}; - b2Settings.b2MixFriction = function (friction1, friction2) { - if (friction1 === undefined) friction1 = 0; - if (friction2 === undefined) friction2 = 0; - return Math.sqrt(friction1 * friction2); - } - b2Settings.b2MixRestitution = function (restitution1, restitution2) { - if (restitution1 === undefined) restitution1 = 0; - if (restitution2 === undefined) restitution2 = 0; - return restitution1 > restitution2 ? restitution1 : restitution2; - } - b2Settings.b2Assert = function (a) { - if (!a) { - throw "Assertion Failed"; - } - } - Box2D.postDefs.push(function () { - Box2D.Common.b2Settings.VERSION = "2.1alpha"; - Box2D.Common.b2Settings.USHRT_MAX = 0x0000ffff; - Box2D.Common.b2Settings.b2_pi = Math.PI; - Box2D.Common.b2Settings.b2_maxManifoldPoints = 2; - Box2D.Common.b2Settings.b2_aabbExtension = 0.1; - Box2D.Common.b2Settings.b2_aabbMultiplier = 2.0; - Box2D.Common.b2Settings.b2_polygonRadius = 2.0 * b2Settings.b2_linearSlop; - Box2D.Common.b2Settings.b2_linearSlop = 0.005; - Box2D.Common.b2Settings.b2_angularSlop = 2.0 / 180.0 * b2Settings.b2_pi; - Box2D.Common.b2Settings.b2_toiSlop = 8.0 * b2Settings.b2_linearSlop; - Box2D.Common.b2Settings.b2_maxTOIContactsPerIsland = 32; - Box2D.Common.b2Settings.b2_maxTOIJointsPerIsland = 32; - Box2D.Common.b2Settings.b2_velocityThreshold = 1.0; - Box2D.Common.b2Settings.b2_maxLinearCorrection = 0.2; - Box2D.Common.b2Settings.b2_maxAngularCorrection = 8.0 / 180.0 * b2Settings.b2_pi; - Box2D.Common.b2Settings.b2_maxTranslation = 2.0; - Box2D.Common.b2Settings.b2_maxTranslationSquared = b2Settings.b2_maxTranslation * b2Settings.b2_maxTranslation; - Box2D.Common.b2Settings.b2_maxRotation = 0.5 * b2Settings.b2_pi; - Box2D.Common.b2Settings.b2_maxRotationSquared = b2Settings.b2_maxRotation * b2Settings.b2_maxRotation; - Box2D.Common.b2Settings.b2_contactBaumgarte = 0.2; - Box2D.Common.b2Settings.b2_timeToSleep = 0.5; - Box2D.Common.b2Settings.b2_linearSleepTolerance = 0.01; - Box2D.Common.b2Settings.b2_angularSleepTolerance = 2.0 / 180.0 * b2Settings.b2_pi; - }); -})(); -(function () { - var b2AABB = Box2D.Collision.b2AABB, - b2Color = Box2D.Common.b2Color, - b2internal = Box2D.Common.b2internal, - b2Settings = Box2D.Common.b2Settings, - b2Mat22 = Box2D.Common.Math.b2Mat22, - b2Mat33 = Box2D.Common.Math.b2Mat33, - b2Math = Box2D.Common.Math.b2Math, - b2Sweep = Box2D.Common.Math.b2Sweep, - b2Transform = Box2D.Common.Math.b2Transform, - b2Vec2 = Box2D.Common.Math.b2Vec2, - b2Vec3 = Box2D.Common.Math.b2Vec3; - - b2Mat22.b2Mat22 = function () { - this.col1 = new b2Vec2(); - this.col2 = new b2Vec2(); - }; - b2Mat22.prototype.b2Mat22 = function () { - this.SetIdentity(); - } - b2Mat22.FromAngle = function (angle) { - if (angle === undefined) angle = 0; - var mat = new b2Mat22(); - mat.Set(angle); - return mat; - } - b2Mat22.FromVV = function (c1, c2) { - var mat = new b2Mat22(); - mat.SetVV(c1, c2); - return mat; - } - b2Mat22.prototype.Set = function (angle) { - if (angle === undefined) angle = 0; - var c = Math.cos(angle); - var s = Math.sin(angle); - this.col1.x = c; - this.col2.x = (-s); - this.col1.y = s; - this.col2.y = c; - } - b2Mat22.prototype.SetVV = function (c1, c2) { - this.col1.SetV(c1); - this.col2.SetV(c2); - } - b2Mat22.prototype.Copy = function () { - var mat = new b2Mat22(); - mat.SetM(this); - return mat; - } - b2Mat22.prototype.SetM = function (m) { - this.col1.SetV(m.col1); - this.col2.SetV(m.col2); - } - b2Mat22.prototype.AddM = function (m) { - this.col1.x += m.col1.x; - this.col1.y += m.col1.y; - this.col2.x += m.col2.x; - this.col2.y += m.col2.y; - } - b2Mat22.prototype.SetIdentity = function () { - this.col1.x = 1.0; - this.col2.x = 0.0; - this.col1.y = 0.0; - this.col2.y = 1.0; - } - b2Mat22.prototype.SetZero = function () { - this.col1.x = 0.0; - this.col2.x = 0.0; - this.col1.y = 0.0; - this.col2.y = 0.0; - } - b2Mat22.prototype.GetAngle = function () { - return Math.atan2(this.col1.y, this.col1.x); - } - b2Mat22.prototype.GetInverse = function (out) { - var a = this.col1.x; - var b = this.col2.x; - var c = this.col1.y; - var d = this.col2.y; - var det = a * d - b * c; - if (det != 0.0) { - det = 1.0 / det; - } - out.col1.x = det * d; - out.col2.x = (-det * b); - out.col1.y = (-det * c); - out.col2.y = det * a; - return out; - } - b2Mat22.prototype.Solve = function (out, bX, bY) { - if (bX === undefined) bX = 0; - if (bY === undefined) bY = 0; - var a11 = this.col1.x; - var a12 = this.col2.x; - var a21 = this.col1.y; - var a22 = this.col2.y; - var det = a11 * a22 - a12 * a21; - if (det != 0.0) { - det = 1.0 / det; - } - out.x = det * (a22 * bX - a12 * bY); - out.y = det * (a11 * bY - a21 * bX); - return out; - } - b2Mat22.prototype.Abs = function () { - this.col1.Abs(); - this.col2.Abs(); - } - b2Mat33.b2Mat33 = function () { - this.col1 = new b2Vec3(); - this.col2 = new b2Vec3(); - this.col3 = new b2Vec3(); - }; - b2Mat33.prototype.b2Mat33 = function (c1, c2, c3) { - if (c1 === undefined) c1 = null; - if (c2 === undefined) c2 = null; - if (c3 === undefined) c3 = null; - if (!c1 && !c2 && !c3) { - this.col1.SetZero(); - this.col2.SetZero(); - this.col3.SetZero(); - } - else { - this.col1.SetV(c1); - this.col2.SetV(c2); - this.col3.SetV(c3); - } - } - b2Mat33.prototype.SetVVV = function (c1, c2, c3) { - this.col1.SetV(c1); - this.col2.SetV(c2); - this.col3.SetV(c3); - } - b2Mat33.prototype.Copy = function () { - return new b2Mat33(this.col1, this.col2, this.col3); - } - b2Mat33.prototype.SetM = function (m) { - this.col1.SetV(m.col1); - this.col2.SetV(m.col2); - this.col3.SetV(m.col3); - } - b2Mat33.prototype.AddM = function (m) { - this.col1.x += m.col1.x; - this.col1.y += m.col1.y; - this.col1.z += m.col1.z; - this.col2.x += m.col2.x; - this.col2.y += m.col2.y; - this.col2.z += m.col2.z; - this.col3.x += m.col3.x; - this.col3.y += m.col3.y; - this.col3.z += m.col3.z; - } - b2Mat33.prototype.SetIdentity = function () { - this.col1.x = 1.0; - this.col2.x = 0.0; - this.col3.x = 0.0; - this.col1.y = 0.0; - this.col2.y = 1.0; - this.col3.y = 0.0; - this.col1.z = 0.0; - this.col2.z = 0.0; - this.col3.z = 1.0; - } - b2Mat33.prototype.SetZero = function () { - this.col1.x = 0.0; - this.col2.x = 0.0; - this.col3.x = 0.0; - this.col1.y = 0.0; - this.col2.y = 0.0; - this.col3.y = 0.0; - this.col1.z = 0.0; - this.col2.z = 0.0; - this.col3.z = 0.0; - } - b2Mat33.prototype.Solve22 = function (out, bX, bY) { - if (bX === undefined) bX = 0; - if (bY === undefined) bY = 0; - var a11 = this.col1.x; - var a12 = this.col2.x; - var a21 = this.col1.y; - var a22 = this.col2.y; - var det = a11 * a22 - a12 * a21; - if (det != 0.0) { - det = 1.0 / det; - } - out.x = det * (a22 * bX - a12 * bY); - out.y = det * (a11 * bY - a21 * bX); - return out; - } - b2Mat33.prototype.Solve33 = function (out, bX, bY, bZ) { - if (bX === undefined) bX = 0; - if (bY === undefined) bY = 0; - if (bZ === undefined) bZ = 0; - var a11 = this.col1.x; - var a21 = this.col1.y; - var a31 = this.col1.z; - var a12 = this.col2.x; - var a22 = this.col2.y; - var a32 = this.col2.z; - var a13 = this.col3.x; - var a23 = this.col3.y; - var a33 = this.col3.z; - var det = a11 * (a22 * a33 - a32 * a23) + a21 * (a32 * a13 - a12 * a33) + a31 * (a12 * a23 - a22 * a13); - if (det != 0.0) { - det = 1.0 / det; - } - out.x = det * (bX * (a22 * a33 - a32 * a23) + bY * (a32 * a13 - a12 * a33) + bZ * (a12 * a23 - a22 * a13)); - out.y = det * (a11 * (bY * a33 - bZ * a23) + a21 * (bZ * a13 - bX * a33) + a31 * (bX * a23 - bY * a13)); - out.z = det * (a11 * (a22 * bZ - a32 * bY) + a21 * (a32 * bX - a12 * bZ) + a31 * (a12 * bY - a22 * bX)); - return out; - } - b2Math.b2Math = function () {}; - b2Math.IsValid = function (x) { - if (x === undefined) x = 0; - return isFinite(x); - } - b2Math.Dot = function (a, b) { - return a.x * b.x + a.y * b.y; - } - b2Math.CrossVV = function (a, b) { - return a.x * b.y - a.y * b.x; - } - b2Math.CrossVF = function (a, s) { - if (s === undefined) s = 0; - var v = new b2Vec2(s * a.y, (-s * a.x)); - return v; - } - b2Math.CrossFV = function (s, a) { - if (s === undefined) s = 0; - var v = new b2Vec2((-s * a.y), s * a.x); - return v; - } - b2Math.MulMV = function (A, v) { - var u = new b2Vec2(A.col1.x * v.x + A.col2.x * v.y, A.col1.y * v.x + A.col2.y * v.y); - return u; - } - b2Math.MulTMV = function (A, v) { - var u = new b2Vec2(b2Math.Dot(v, A.col1), b2Math.Dot(v, A.col2)); - return u; - } - b2Math.MulX = function (T, v) { - var a = b2Math.MulMV(T.R, v); - a.x += T.position.x; - a.y += T.position.y; - return a; - } - b2Math.MulXT = function (T, v) { - var a = b2Math.SubtractVV(v, T.position); - var tX = (a.x * T.R.col1.x + a.y * T.R.col1.y); - a.y = (a.x * T.R.col2.x + a.y * T.R.col2.y); - a.x = tX; - return a; - } - b2Math.AddVV = function (a, b) { - var v = new b2Vec2(a.x + b.x, a.y + b.y); - return v; - } - b2Math.SubtractVV = function (a, b) { - var v = new b2Vec2(a.x - b.x, a.y - b.y); - return v; - } - b2Math.Distance = function (a, b) { - var cX = a.x - b.x; - var cY = a.y - b.y; - return Math.sqrt(cX * cX + cY * cY); - } - b2Math.DistanceSquared = function (a, b) { - var cX = a.x - b.x; - var cY = a.y - b.y; - return (cX * cX + cY * cY); - } - b2Math.MulFV = function (s, a) { - if (s === undefined) s = 0; - var v = new b2Vec2(s * a.x, s * a.y); - return v; - } - b2Math.AddMM = function (A, B) { - var C = b2Mat22.FromVV(b2Math.AddVV(A.col1, B.col1), b2Math.AddVV(A.col2, B.col2)); - return C; - } - b2Math.MulMM = function (A, B) { - var C = b2Mat22.FromVV(b2Math.MulMV(A, B.col1), b2Math.MulMV(A, B.col2)); - return C; - } - b2Math.MulTMM = function (A, B) { - var c1 = new b2Vec2(b2Math.Dot(A.col1, B.col1), b2Math.Dot(A.col2, B.col1)); - var c2 = new b2Vec2(b2Math.Dot(A.col1, B.col2), b2Math.Dot(A.col2, B.col2)); - var C = b2Mat22.FromVV(c1, c2); - return C; - } - b2Math.Abs = function (a) { - if (a === undefined) a = 0; - return a > 0.0 ? a : (-a); - } - b2Math.AbsV = function (a) { - var b = new b2Vec2(b2Math.Abs(a.x), b2Math.Abs(a.y)); - return b; - } - b2Math.AbsM = function (A) { - var B = b2Mat22.FromVV(b2Math.AbsV(A.col1), b2Math.AbsV(A.col2)); - return B; - } - b2Math.Min = function (a, b) { - if (a === undefined) a = 0; - if (b === undefined) b = 0; - return a < b ? a : b; - } - b2Math.MinV = function (a, b) { - var c = new b2Vec2(b2Math.Min(a.x, b.x), b2Math.Min(a.y, b.y)); - return c; - } - b2Math.Max = function (a, b) { - if (a === undefined) a = 0; - if (b === undefined) b = 0; - return a > b ? a : b; - } - b2Math.MaxV = function (a, b) { - var c = new b2Vec2(b2Math.Max(a.x, b.x), b2Math.Max(a.y, b.y)); - return c; - } - b2Math.Clamp = function (a, low, high) { - if (a === undefined) a = 0; - if (low === undefined) low = 0; - if (high === undefined) high = 0; - return a < low ? low : a > high ? high : a; - } - b2Math.ClampV = function (a, low, high) { - return b2Math.MaxV(low, b2Math.MinV(a, high)); - } - b2Math.Swap = function (a, b) { - var tmp = a[0]; - a[0] = b[0]; - b[0] = tmp; - } - b2Math.Random = function () { - return Math.random() * 2 - 1; - } - b2Math.RandomRange = function (lo, hi) { - if (lo === undefined) lo = 0; - if (hi === undefined) hi = 0; - var r = Math.random(); - r = (hi - lo) * r + lo; - return r; - } - b2Math.NextPowerOfTwo = function (x) { - if (x === undefined) x = 0; - x |= (x >> 1) & 0x7FFFFFFF; - x |= (x >> 2) & 0x3FFFFFFF; - x |= (x >> 4) & 0x0FFFFFFF; - x |= (x >> 8) & 0x00FFFFFF; - x |= (x >> 16) & 0x0000FFFF; - return x + 1; - } - b2Math.IsPowerOfTwo = function (x) { - if (x === undefined) x = 0; - var result = x > 0 && (x & (x - 1)) == 0; - return result; - } - Box2D.postDefs.push(function () { - Box2D.Common.Math.b2Math.b2Vec2_zero = new b2Vec2(0.0, 0.0); - Box2D.Common.Math.b2Math.b2Mat22_identity = b2Mat22.FromVV(new b2Vec2(1.0, 0.0), new b2Vec2(0.0, 1.0)); - Box2D.Common.Math.b2Math.b2Transform_identity = new b2Transform(b2Math.b2Vec2_zero, b2Math.b2Mat22_identity); - }); - b2Sweep.b2Sweep = function () { - this.localCenter = new b2Vec2(); - this.c0 = new b2Vec2; - this.c = new b2Vec2(); - }; - b2Sweep.prototype.Set = function (other) { - this.localCenter.SetV(other.localCenter); - this.c0.SetV(other.c0); - this.c.SetV(other.c); - this.a0 = other.a0; - this.a = other.a; - this.t0 = other.t0; - } - b2Sweep.prototype.Copy = function () { - var copy = new b2Sweep(); - copy.localCenter.SetV(this.localCenter); - copy.c0.SetV(this.c0); - copy.c.SetV(this.c); - copy.a0 = this.a0; - copy.a = this.a; - copy.t0 = this.t0; - return copy; - } - b2Sweep.prototype.GetTransform = function (xf, alpha) { - if (alpha === undefined) alpha = 0; - xf.position.x = (1.0 - alpha) * this.c0.x + alpha * this.c.x; - xf.position.y = (1.0 - alpha) * this.c0.y + alpha * this.c.y; - var angle = (1.0 - alpha) * this.a0 + alpha * this.a; - xf.R.Set(angle); - var tMat = xf.R; - xf.position.x -= (tMat.col1.x * this.localCenter.x + tMat.col2.x * this.localCenter.y); - xf.position.y -= (tMat.col1.y * this.localCenter.x + tMat.col2.y * this.localCenter.y); - } - b2Sweep.prototype.Advance = function (t) { - if (t === undefined) t = 0; - if (this.t0 < t && 1.0 - this.t0 > Number.MIN_VALUE) { - var alpha = (t - this.t0) / (1.0 - this.t0); - this.c0.x = (1.0 - alpha) * this.c0.x + alpha * this.c.x; - this.c0.y = (1.0 - alpha) * this.c0.y + alpha * this.c.y; - this.a0 = (1.0 - alpha) * this.a0 + alpha * this.a; - this.t0 = t; - } - } - b2Transform.b2Transform = function () { - this.position = new b2Vec2; - this.R = new b2Mat22(); - }; - b2Transform.prototype.b2Transform = function (pos, r) { - if (pos === undefined) pos = null; - if (r === undefined) r = null; - if (pos) { - this.position.SetV(pos); - this.R.SetM(r); - } - } - b2Transform.prototype.Initialize = function (pos, r) { - this.position.SetV(pos); - this.R.SetM(r); - } - b2Transform.prototype.SetIdentity = function () { - this.position.SetZero(); - this.R.SetIdentity(); - } - b2Transform.prototype.Set = function (x) { - this.position.SetV(x.position); - this.R.SetM(x.R); - } - b2Transform.prototype.GetAngle = function () { - return Math.atan2(this.R.col1.y, this.R.col1.x); - } - b2Vec2.b2Vec2 = function () {}; - b2Vec2.prototype.b2Vec2 = function (x_, y_) { - if (x_ === undefined) x_ = 0; - if (y_ === undefined) y_ = 0; - this.x = x_; - this.y = y_; - } - b2Vec2.prototype.SetZero = function () { - this.x = 0.0; - this.y = 0.0; - } - b2Vec2.prototype.Set = function (x_, y_) { - if (x_ === undefined) x_ = 0; - if (y_ === undefined) y_ = 0; - this.x = x_; - this.y = y_; - } - b2Vec2.prototype.SetV = function (v) { - this.x = v.x; - this.y = v.y; - } - b2Vec2.prototype.GetNegative = function () { - return new b2Vec2((-this.x), (-this.y)); - } - b2Vec2.prototype.NegativeSelf = function () { - this.x = (-this.x); - this.y = (-this.y); - } - b2Vec2.Make = function (x_, y_) { - if (x_ === undefined) x_ = 0; - if (y_ === undefined) y_ = 0; - return new b2Vec2(x_, y_); - } - b2Vec2.prototype.Copy = function () { - return new b2Vec2(this.x, this.y); - } - b2Vec2.prototype.Add = function (v) { - this.x += v.x; - this.y += v.y; - } - b2Vec2.prototype.Subtract = function (v) { - this.x -= v.x; - this.y -= v.y; - } - b2Vec2.prototype.Multiply = function (a) { - if (a === undefined) a = 0; - this.x *= a; - this.y *= a; - } - b2Vec2.prototype.MulM = function (A) { - var tX = this.x; - this.x = A.col1.x * tX + A.col2.x * this.y; - this.y = A.col1.y * tX + A.col2.y * this.y; - } - b2Vec2.prototype.MulTM = function (A) { - var tX = b2Math.Dot(this, A.col1); - this.y = b2Math.Dot(this, A.col2); - this.x = tX; - } - b2Vec2.prototype.CrossVF = function (s) { - if (s === undefined) s = 0; - var tX = this.x; - this.x = s * this.y; - this.y = (-s * tX); - } - b2Vec2.prototype.CrossFV = function (s) { - if (s === undefined) s = 0; - var tX = this.x; - this.x = (-s * this.y); - this.y = s * tX; - } - b2Vec2.prototype.MinV = function (b) { - this.x = this.x < b.x ? this.x : b.x; - this.y = this.y < b.y ? this.y : b.y; - } - b2Vec2.prototype.MaxV = function (b) { - this.x = this.x > b.x ? this.x : b.x; - this.y = this.y > b.y ? this.y : b.y; - } - b2Vec2.prototype.Abs = function () { - if (this.x < 0) this.x = (-this.x); - if (this.y < 0) this.y = (-this.y); - } - b2Vec2.prototype.Length = function () { - return Math.sqrt(this.x * this.x + this.y * this.y); - } - b2Vec2.prototype.LengthSquared = function () { - return (this.x * this.x + this.y * this.y); - } - b2Vec2.prototype.Normalize = function () { - var length = Math.sqrt(this.x * this.x + this.y * this.y); - if (length < Number.MIN_VALUE) { - return 0.0; - } - var invLength = 1.0 / length; - this.x *= invLength; - this.y *= invLength; - return length; - } - b2Vec2.prototype.IsValid = function () { - return b2Math.IsValid(this.x) && b2Math.IsValid(this.y); - } - b2Vec3.b2Vec3 = function () {}; - b2Vec3.prototype.b2Vec3 = function (x, y, z) { - if (x === undefined) x = 0; - if (y === undefined) y = 0; - if (z === undefined) z = 0; - this.x = x; - this.y = y; - this.z = z; - } - b2Vec3.prototype.SetZero = function () { - this.x = this.y = this.z = 0.0; - } - b2Vec3.prototype.Set = function (x, y, z) { - if (x === undefined) x = 0; - if (y === undefined) y = 0; - if (z === undefined) z = 0; - this.x = x; - this.y = y; - this.z = z; - } - b2Vec3.prototype.SetV = function (v) { - this.x = v.x; - this.y = v.y; - this.z = v.z; - } - b2Vec3.prototype.GetNegative = function () { - return new b2Vec3((-this.x), (-this.y), (-this.z)); - } - b2Vec3.prototype.NegativeSelf = function () { - this.x = (-this.x); - this.y = (-this.y); - this.z = (-this.z); - } - b2Vec3.prototype.Copy = function () { - return new b2Vec3(this.x, this.y, this.z); - } - b2Vec3.prototype.Add = function (v) { - this.x += v.x; - this.y += v.y; - this.z += v.z; - } - b2Vec3.prototype.Subtract = function (v) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z; - } - b2Vec3.prototype.Multiply = function (a) { - if (a === undefined) a = 0; - this.x *= a; - this.y *= a; - this.z *= a; - } -})(); -(function () { - var b2ControllerEdge = Box2D.Dynamics.Controllers.b2ControllerEdge, - b2Mat22 = Box2D.Common.Math.b2Mat22, - b2Mat33 = Box2D.Common.Math.b2Mat33, - b2Math = Box2D.Common.Math.b2Math, - b2Sweep = Box2D.Common.Math.b2Sweep, - b2Transform = Box2D.Common.Math.b2Transform, - b2Vec2 = Box2D.Common.Math.b2Vec2, - b2Vec3 = Box2D.Common.Math.b2Vec3, - b2Color = Box2D.Common.b2Color, - b2internal = Box2D.Common.b2internal, - b2Settings = Box2D.Common.b2Settings, - b2AABB = Box2D.Collision.b2AABB, - b2Bound = Box2D.Collision.b2Bound, - b2BoundValues = Box2D.Collision.b2BoundValues, - b2Collision = Box2D.Collision.b2Collision, - b2ContactID = Box2D.Collision.b2ContactID, - b2ContactPoint = Box2D.Collision.b2ContactPoint, - b2Distance = Box2D.Collision.b2Distance, - b2DistanceInput = Box2D.Collision.b2DistanceInput, - b2DistanceOutput = Box2D.Collision.b2DistanceOutput, - b2DistanceProxy = Box2D.Collision.b2DistanceProxy, - b2DynamicTree = Box2D.Collision.b2DynamicTree, - b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase, - b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode, - b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair, - b2Manifold = Box2D.Collision.b2Manifold, - b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint, - b2Point = Box2D.Collision.b2Point, - b2RayCastInput = Box2D.Collision.b2RayCastInput, - b2RayCastOutput = Box2D.Collision.b2RayCastOutput, - b2Segment = Box2D.Collision.b2Segment, - b2SeparationFunction = Box2D.Collision.b2SeparationFunction, - b2Simplex = Box2D.Collision.b2Simplex, - b2SimplexCache = Box2D.Collision.b2SimplexCache, - b2SimplexVertex = Box2D.Collision.b2SimplexVertex, - b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact, - b2TOIInput = Box2D.Collision.b2TOIInput, - b2WorldManifold = Box2D.Collision.b2WorldManifold, - ClipVertex = Box2D.Collision.ClipVertex, - Features = Box2D.Collision.Features, - IBroadPhase = Box2D.Collision.IBroadPhase, - b2CircleShape = Box2D.Collision.Shapes.b2CircleShape, - b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef, - b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape, - b2MassData = Box2D.Collision.Shapes.b2MassData, - b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape, - b2Shape = Box2D.Collision.Shapes.b2Shape, - b2Body = Box2D.Dynamics.b2Body, - b2BodyDef = Box2D.Dynamics.b2BodyDef, - b2ContactFilter = Box2D.Dynamics.b2ContactFilter, - b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse, - b2ContactListener = Box2D.Dynamics.b2ContactListener, - b2ContactManager = Box2D.Dynamics.b2ContactManager, - b2DebugDraw = Box2D.Dynamics.b2DebugDraw, - b2DestructionListener = Box2D.Dynamics.b2DestructionListener, - b2FilterData = Box2D.Dynamics.b2FilterData, - b2Fixture = Box2D.Dynamics.b2Fixture, - b2FixtureDef = Box2D.Dynamics.b2FixtureDef, - b2Island = Box2D.Dynamics.b2Island, - b2TimeStep = Box2D.Dynamics.b2TimeStep, - b2World = Box2D.Dynamics.b2World, - b2CircleContact = Box2D.Dynamics.Contacts.b2CircleContact, - b2Contact = Box2D.Dynamics.Contacts.b2Contact, - b2ContactConstraint = Box2D.Dynamics.Contacts.b2ContactConstraint, - b2ContactConstraintPoint = Box2D.Dynamics.Contacts.b2ContactConstraintPoint, - b2ContactEdge = Box2D.Dynamics.Contacts.b2ContactEdge, - b2ContactFactory = Box2D.Dynamics.Contacts.b2ContactFactory, - b2ContactRegister = Box2D.Dynamics.Contacts.b2ContactRegister, - b2ContactResult = Box2D.Dynamics.Contacts.b2ContactResult, - b2ContactSolver = Box2D.Dynamics.Contacts.b2ContactSolver, - b2EdgeAndCircleContact = Box2D.Dynamics.Contacts.b2EdgeAndCircleContact, - b2NullContact = Box2D.Dynamics.Contacts.b2NullContact, - b2PolyAndCircleContact = Box2D.Dynamics.Contacts.b2PolyAndCircleContact, - b2PolyAndEdgeContact = Box2D.Dynamics.Contacts.b2PolyAndEdgeContact, - b2PolygonContact = Box2D.Dynamics.Contacts.b2PolygonContact, - b2PositionSolverManifold = Box2D.Dynamics.Contacts.b2PositionSolverManifold, - b2Controller = Box2D.Dynamics.Controllers.b2Controller, - b2DistanceJoint = Box2D.Dynamics.Joints.b2DistanceJoint, - b2DistanceJointDef = Box2D.Dynamics.Joints.b2DistanceJointDef, - b2FrictionJoint = Box2D.Dynamics.Joints.b2FrictionJoint, - b2FrictionJointDef = Box2D.Dynamics.Joints.b2FrictionJointDef, - b2GearJoint = Box2D.Dynamics.Joints.b2GearJoint, - b2GearJointDef = Box2D.Dynamics.Joints.b2GearJointDef, - b2Jacobian = Box2D.Dynamics.Joints.b2Jacobian, - b2Joint = Box2D.Dynamics.Joints.b2Joint, - b2JointDef = Box2D.Dynamics.Joints.b2JointDef, - b2JointEdge = Box2D.Dynamics.Joints.b2JointEdge, - b2LineJoint = Box2D.Dynamics.Joints.b2LineJoint, - b2LineJointDef = Box2D.Dynamics.Joints.b2LineJointDef, - b2MouseJoint = Box2D.Dynamics.Joints.b2MouseJoint, - b2MouseJointDef = Box2D.Dynamics.Joints.b2MouseJointDef, - b2PrismaticJoint = Box2D.Dynamics.Joints.b2PrismaticJoint, - b2PrismaticJointDef = Box2D.Dynamics.Joints.b2PrismaticJointDef, - b2PulleyJoint = Box2D.Dynamics.Joints.b2PulleyJoint, - b2PulleyJointDef = Box2D.Dynamics.Joints.b2PulleyJointDef, - b2RevoluteJoint = Box2D.Dynamics.Joints.b2RevoluteJoint, - b2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef, - b2WeldJoint = Box2D.Dynamics.Joints.b2WeldJoint, - b2WeldJointDef = Box2D.Dynamics.Joints.b2WeldJointDef; - - b2Body.b2Body = function () { - this.m_xf = new b2Transform(); - this.m_sweep = new b2Sweep(); - this.m_linearVelocity = new b2Vec2(); - this.m_force = new b2Vec2(); - }; - b2Body.prototype.connectEdges = function (s1, s2, angle1) { - if (angle1 === undefined) angle1 = 0; - var angle2 = Math.atan2(s2.GetDirectionVector().y, s2.GetDirectionVector().x); - var coreOffset = Math.tan((angle2 - angle1) * 0.5); - var core = b2Math.MulFV(coreOffset, s2.GetDirectionVector()); - core = b2Math.SubtractVV(core, s2.GetNormalVector()); - core = b2Math.MulFV(b2Settings.b2_toiSlop, core); - core = b2Math.AddVV(core, s2.GetVertex1()); - var cornerDir = b2Math.AddVV(s1.GetDirectionVector(), s2.GetDirectionVector()); - cornerDir.Normalize(); - var convex = b2Math.Dot(s1.GetDirectionVector(), s2.GetNormalVector()) > 0.0; - s1.SetNextEdge(s2, core, cornerDir, convex); - s2.SetPrevEdge(s1, core, cornerDir, convex); - return angle2; - } - b2Body.prototype.CreateFixture = function (def) { - if (this.m_world.IsLocked() == true) { - return null; - } - var fixture = new b2Fixture(); - fixture.Create(this, this.m_xf, def); - if (this.m_flags & b2Body.e_activeFlag) { - var broadPhase = this.m_world.m_contactManager.m_broadPhase; - fixture.CreateProxy(broadPhase, this.m_xf); - } - fixture.m_next = this.m_fixtureList; - this.m_fixtureList = fixture; - ++this.m_fixtureCount; - fixture.m_body = this; - if (fixture.m_density > 0.0) { - this.ResetMassData(); - } - this.m_world.m_flags |= b2World.e_newFixture; - return fixture; - } - b2Body.prototype.CreateFixture2 = function (shape, density) { - if (density === undefined) density = 0.0; - var def = new b2FixtureDef(); - def.shape = shape; - def.density = density; - return this.CreateFixture(def); - } - b2Body.prototype.DestroyFixture = function (fixture) { - if (this.m_world.IsLocked() == true) { - return; - } - var node = this.m_fixtureList; - var ppF = null; - var found = false; - while (node != null) { - if (node == fixture) { - if (ppF) ppF.m_next = fixture.m_next; - else this.m_fixtureList = fixture.m_next; - found = true; - break; - } - ppF = node; - node = node.m_next; - } - var edge = this.m_contactList; - while (edge) { - var c = edge.contact; - edge = edge.next; - var fixtureA = c.GetFixtureA(); - var fixtureB = c.GetFixtureB(); - if (fixture == fixtureA || fixture == fixtureB) { - this.m_world.m_contactManager.Destroy(c); - } - } - if (this.m_flags & b2Body.e_activeFlag) { - var broadPhase = this.m_world.m_contactManager.m_broadPhase; - fixture.DestroyProxy(broadPhase); - } - else {} - fixture.Destroy(); - fixture.m_body = null; - fixture.m_next = null; - --this.m_fixtureCount; - this.ResetMassData(); - } - b2Body.prototype.SetPositionAndAngle = function (position, angle) { - if (angle === undefined) angle = 0; - var f; - if (this.m_world.IsLocked() == true) { - return; - } - this.m_xf.R.Set(angle); - this.m_xf.position.SetV(position); - var tMat = this.m_xf.R; - var tVec = this.m_sweep.localCenter; - this.m_sweep.c.x = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - this.m_sweep.c.y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - this.m_sweep.c.x += this.m_xf.position.x; - this.m_sweep.c.y += this.m_xf.position.y; - this.m_sweep.c0.SetV(this.m_sweep.c); - this.m_sweep.a0 = this.m_sweep.a = angle; - var broadPhase = this.m_world.m_contactManager.m_broadPhase; - for (f = this.m_fixtureList; - f; f = f.m_next) { - f.Synchronize(broadPhase, this.m_xf, this.m_xf); - } - this.m_world.m_contactManager.FindNewContacts(); - } - b2Body.prototype.SetTransform = function (xf) { - this.SetPositionAndAngle(xf.position, xf.GetAngle()); - } - b2Body.prototype.GetTransform = function () { - return this.m_xf; - } - b2Body.prototype.GetPosition = function () { - return this.m_xf.position; - } - b2Body.prototype.SetPosition = function (position) { - this.SetPositionAndAngle(position, this.GetAngle()); - } - b2Body.prototype.GetAngle = function () { - return this.m_sweep.a; - } - b2Body.prototype.SetAngle = function (angle) { - if (angle === undefined) angle = 0; - this.SetPositionAndAngle(this.GetPosition(), angle); - } - b2Body.prototype.GetWorldCenter = function () { - return this.m_sweep.c; - } - b2Body.prototype.GetLocalCenter = function () { - return this.m_sweep.localCenter; - } - b2Body.prototype.SetLinearVelocity = function (v) { - if (this.m_type == b2Body.b2_staticBody) { - return; - } - this.m_linearVelocity.SetV(v); - } - b2Body.prototype.GetLinearVelocity = function () { - return this.m_linearVelocity; - } - b2Body.prototype.SetAngularVelocity = function (omega) { - if (omega === undefined) omega = 0; - if (this.m_type == b2Body.b2_staticBody) { - return; - } - this.m_angularVelocity = omega; - } - b2Body.prototype.GetAngularVelocity = function () { - return this.m_angularVelocity; - } - b2Body.prototype.GetDefinition = function () { - var bd = new b2BodyDef(); - bd.type = this.GetType(); - bd.allowSleep = (this.m_flags & b2Body.e_allowSleepFlag) == b2Body.e_allowSleepFlag; - bd.angle = this.GetAngle(); - bd.angularDamping = this.m_angularDamping; - bd.angularVelocity = this.m_angularVelocity; - bd.fixedRotation = (this.m_flags & b2Body.e_fixedRotationFlag) == b2Body.e_fixedRotationFlag; - bd.bullet = (this.m_flags & b2Body.e_bulletFlag) == b2Body.e_bulletFlag; - bd.awake = (this.m_flags & b2Body.e_awakeFlag) == b2Body.e_awakeFlag; - bd.linearDamping = this.m_linearDamping; - bd.linearVelocity.SetV(this.GetLinearVelocity()); - bd.position = this.GetPosition(); - bd.userData = this.GetUserData(); - return bd; - } - b2Body.prototype.ApplyForce = function (force, point) { - if (this.m_type != b2Body.b2_dynamicBody) { - return; - } - if (this.IsAwake() == false) { - this.SetAwake(true); - } - this.m_force.x += force.x; - this.m_force.y += force.y; - this.m_torque += ((point.x - this.m_sweep.c.x) * force.y - (point.y - this.m_sweep.c.y) * force.x); - } - b2Body.prototype.ApplyTorque = function (torque) { - if (torque === undefined) torque = 0; - if (this.m_type != b2Body.b2_dynamicBody) { - return; - } - if (this.IsAwake() == false) { - this.SetAwake(true); - } - this.m_torque += torque; - } - b2Body.prototype.ApplyImpulse = function (impulse, point) { - if (this.m_type != b2Body.b2_dynamicBody) { - return; - } - if (this.IsAwake() == false) { - this.SetAwake(true); - } - this.m_linearVelocity.x += this.m_invMass * impulse.x; - this.m_linearVelocity.y += this.m_invMass * impulse.y; - this.m_angularVelocity += this.m_invI * ((point.x - this.m_sweep.c.x) * impulse.y - (point.y - this.m_sweep.c.y) * impulse.x); - } - b2Body.prototype.Split = function (callback) { - var linearVelocity = this.GetLinearVelocity().Copy(); - var angularVelocity = this.GetAngularVelocity(); - var center = this.GetWorldCenter(); - var body1 = this; - var body2 = this.m_world.CreateBody(this.GetDefinition()); - var prev; - for (var f = body1.m_fixtureList; f;) { - if (callback(f)) { - var next = f.m_next; - if (prev) { - prev.m_next = next; - } - else { - body1.m_fixtureList = next; - } - body1.m_fixtureCount--; - f.m_next = body2.m_fixtureList; - body2.m_fixtureList = f; - body2.m_fixtureCount++; - f.m_body = body2; - f = next; - } - else { - prev = f; - f = f.m_next; - } - } - body1.ResetMassData(); - body2.ResetMassData(); - var center1 = body1.GetWorldCenter(); - var center2 = body2.GetWorldCenter(); - var velocity1 = b2Math.AddVV(linearVelocity, b2Math.CrossFV(angularVelocity, b2Math.SubtractVV(center1, center))); - var velocity2 = b2Math.AddVV(linearVelocity, b2Math.CrossFV(angularVelocity, b2Math.SubtractVV(center2, center))); - body1.SetLinearVelocity(velocity1); - body2.SetLinearVelocity(velocity2); - body1.SetAngularVelocity(angularVelocity); - body2.SetAngularVelocity(angularVelocity); - body1.SynchronizeFixtures(); - body2.SynchronizeFixtures(); - return body2; - } - b2Body.prototype.Merge = function (other) { - var f; - for (f = other.m_fixtureList; - f;) { - var next = f.m_next; - other.m_fixtureCount--; - f.m_next = this.m_fixtureList; - this.m_fixtureList = f; - this.m_fixtureCount++; - f.m_body = body2; - f = next; - } - body1.m_fixtureCount = 0; - var body1 = this; - var body2 = other; - var center1 = body1.GetWorldCenter(); - var center2 = body2.GetWorldCenter(); - var velocity1 = body1.GetLinearVelocity().Copy(); - var velocity2 = body2.GetLinearVelocity().Copy(); - var angular1 = body1.GetAngularVelocity(); - var angular = body2.GetAngularVelocity(); - body1.ResetMassData(); - this.SynchronizeFixtures(); - } - b2Body.prototype.GetMass = function () { - return this.m_mass; - } - b2Body.prototype.GetInertia = function () { - return this.m_I; - } - b2Body.prototype.GetMassData = function (data) { - data.mass = this.m_mass; - data.I = this.m_I; - data.center.SetV(this.m_sweep.localCenter); - } - b2Body.prototype.SetMassData = function (massData) { - b2Settings.b2Assert(this.m_world.IsLocked() == false); - if (this.m_world.IsLocked() == true) { - return; - } - if (this.m_type != b2Body.b2_dynamicBody) { - return; - } - this.m_invMass = 0.0; - this.m_I = 0.0; - this.m_invI = 0.0; - this.m_mass = massData.mass; - if (this.m_mass <= 0.0) { - this.m_mass = 1.0; - } - this.m_invMass = 1.0 / this.m_mass; - if (massData.I > 0.0 && (this.m_flags & b2Body.e_fixedRotationFlag) == 0) { - this.m_I = massData.I - this.m_mass * (massData.center.x * massData.center.x + massData.center.y * massData.center.y); - this.m_invI = 1.0 / this.m_I; - } - var oldCenter = this.m_sweep.c.Copy(); - this.m_sweep.localCenter.SetV(massData.center); - this.m_sweep.c0.SetV(b2Math.MulX(this.m_xf, this.m_sweep.localCenter)); - this.m_sweep.c.SetV(this.m_sweep.c0); - this.m_linearVelocity.x += this.m_angularVelocity * (-(this.m_sweep.c.y - oldCenter.y)); - this.m_linearVelocity.y += this.m_angularVelocity * (+(this.m_sweep.c.x - oldCenter.x)); - } - b2Body.prototype.ResetMassData = function () { - this.m_mass = 0.0; - this.m_invMass = 0.0; - this.m_I = 0.0; - this.m_invI = 0.0; - this.m_sweep.localCenter.SetZero(); - if (this.m_type == b2Body.b2_staticBody || this.m_type == b2Body.b2_kinematicBody) { - return; - } - var center = b2Vec2.Make(0, 0); - for (var f = this.m_fixtureList; f; f = f.m_next) { - if (f.m_density == 0.0) { - continue; - } - var massData = f.GetMassData(); - this.m_mass += massData.mass; - center.x += massData.center.x * massData.mass; - center.y += massData.center.y * massData.mass; - this.m_I += massData.I; - } - if (this.m_mass > 0.0) { - this.m_invMass = 1.0 / this.m_mass; - center.x *= this.m_invMass; - center.y *= this.m_invMass; - } - else { - this.m_mass = 1.0; - this.m_invMass = 1.0; - } - if (this.m_I > 0.0 && (this.m_flags & b2Body.e_fixedRotationFlag) == 0) { - this.m_I -= this.m_mass * (center.x * center.x + center.y * center.y); - this.m_I *= this.m_inertiaScale; - b2Settings.b2Assert(this.m_I > 0); - this.m_invI = 1.0 / this.m_I; - } - else { - this.m_I = 0.0; - this.m_invI = 0.0; - } - var oldCenter = this.m_sweep.c.Copy(); - this.m_sweep.localCenter.SetV(center); - this.m_sweep.c0.SetV(b2Math.MulX(this.m_xf, this.m_sweep.localCenter)); - this.m_sweep.c.SetV(this.m_sweep.c0); - this.m_linearVelocity.x += this.m_angularVelocity * (-(this.m_sweep.c.y - oldCenter.y)); - this.m_linearVelocity.y += this.m_angularVelocity * (+(this.m_sweep.c.x - oldCenter.x)); - } - b2Body.prototype.GetWorldPoint = function (localPoint) { - var A = this.m_xf.R; - var u = new b2Vec2(A.col1.x * localPoint.x + A.col2.x * localPoint.y, A.col1.y * localPoint.x + A.col2.y * localPoint.y); - u.x += this.m_xf.position.x; - u.y += this.m_xf.position.y; - return u; - } - b2Body.prototype.GetWorldVector = function (localVector) { - return b2Math.MulMV(this.m_xf.R, localVector); - } - b2Body.prototype.GetLocalPoint = function (worldPoint) { - return b2Math.MulXT(this.m_xf, worldPoint); - } - b2Body.prototype.GetLocalVector = function (worldVector) { - return b2Math.MulTMV(this.m_xf.R, worldVector); - } - b2Body.prototype.GetLinearVelocityFromWorldPoint = function (worldPoint) { - return new b2Vec2(this.m_linearVelocity.x - this.m_angularVelocity * (worldPoint.y - this.m_sweep.c.y), this.m_linearVelocity.y + this.m_angularVelocity * (worldPoint.x - this.m_sweep.c.x)); - } - b2Body.prototype.GetLinearVelocityFromLocalPoint = function (localPoint) { - var A = this.m_xf.R; - var worldPoint = new b2Vec2(A.col1.x * localPoint.x + A.col2.x * localPoint.y, A.col1.y * localPoint.x + A.col2.y * localPoint.y); - worldPoint.x += this.m_xf.position.x; - worldPoint.y += this.m_xf.position.y; - return new b2Vec2(this.m_linearVelocity.x - this.m_angularVelocity * (worldPoint.y - this.m_sweep.c.y), this.m_linearVelocity.y + this.m_angularVelocity * (worldPoint.x - this.m_sweep.c.x)); - } - b2Body.prototype.GetLinearDamping = function () { - return this.m_linearDamping; - } - b2Body.prototype.SetLinearDamping = function (linearDamping) { - if (linearDamping === undefined) linearDamping = 0; - this.m_linearDamping = linearDamping; - } - b2Body.prototype.GetAngularDamping = function () { - return this.m_angularDamping; - } - b2Body.prototype.SetAngularDamping = function (angularDamping) { - if (angularDamping === undefined) angularDamping = 0; - this.m_angularDamping = angularDamping; - } - b2Body.prototype.SetType = function (type) { - if (type === undefined) type = 0; - if (this.m_type == type) { - return; - } - this.m_type = type; - this.ResetMassData(); - if (this.m_type == b2Body.b2_staticBody) { - this.m_linearVelocity.SetZero(); - this.m_angularVelocity = 0.0; - } - this.SetAwake(true); - this.m_force.SetZero(); - this.m_torque = 0.0; - for (var ce = this.m_contactList; ce; ce = ce.next) { - ce.contact.FlagForFiltering(); - } - } - b2Body.prototype.GetType = function () { - return this.m_type; - } - b2Body.prototype.SetBullet = function (flag) { - if (flag) { - this.m_flags |= b2Body.e_bulletFlag; - } - else { - this.m_flags &= ~b2Body.e_bulletFlag; - } - } - b2Body.prototype.IsBullet = function () { - return (this.m_flags & b2Body.e_bulletFlag) == b2Body.e_bulletFlag; - } - b2Body.prototype.SetSleepingAllowed = function (flag) { - if (flag) { - this.m_flags |= b2Body.e_allowSleepFlag; - } - else { - this.m_flags &= ~b2Body.e_allowSleepFlag; - this.SetAwake(true); - } - } - b2Body.prototype.SetAwake = function (flag) { - if (flag) { - this.m_flags |= b2Body.e_awakeFlag; - this.m_sleepTime = 0.0; - } - else { - this.m_flags &= ~b2Body.e_awakeFlag; - this.m_sleepTime = 0.0; - this.m_linearVelocity.SetZero(); - this.m_angularVelocity = 0.0; - this.m_force.SetZero(); - this.m_torque = 0.0; - } - } - b2Body.prototype.IsAwake = function () { - return (this.m_flags & b2Body.e_awakeFlag) == b2Body.e_awakeFlag; - } - b2Body.prototype.SetFixedRotation = function (fixed) { - if (fixed) { - this.m_flags |= b2Body.e_fixedRotationFlag; - } - else { - this.m_flags &= ~b2Body.e_fixedRotationFlag; - } - this.ResetMassData(); - } - b2Body.prototype.IsFixedRotation = function () { - return (this.m_flags & b2Body.e_fixedRotationFlag) == b2Body.e_fixedRotationFlag; - } - b2Body.prototype.SetActive = function (flag) { - if (flag == this.IsActive()) { - return; - } - var broadPhase; - var f; - if (flag) { - this.m_flags |= b2Body.e_activeFlag; - broadPhase = this.m_world.m_contactManager.m_broadPhase; - for (f = this.m_fixtureList; - f; f = f.m_next) { - f.CreateProxy(broadPhase, this.m_xf); - } - } - else { - this.m_flags &= ~b2Body.e_activeFlag; - broadPhase = this.m_world.m_contactManager.m_broadPhase; - for (f = this.m_fixtureList; - f; f = f.m_next) { - f.DestroyProxy(broadPhase); - } - var ce = this.m_contactList; - while (ce) { - var ce0 = ce; - ce = ce.next; - this.m_world.m_contactManager.Destroy(ce0.contact); - } - this.m_contactList = null; - } - } - b2Body.prototype.IsActive = function () { - return (this.m_flags & b2Body.e_activeFlag) == b2Body.e_activeFlag; - } - b2Body.prototype.IsSleepingAllowed = function () { - return (this.m_flags & b2Body.e_allowSleepFlag) == b2Body.e_allowSleepFlag; - } - b2Body.prototype.GetFixtureList = function () { - return this.m_fixtureList; - } - b2Body.prototype.GetJointList = function () { - return this.m_jointList; - } - b2Body.prototype.GetControllerList = function () { - return this.m_controllerList; - } - b2Body.prototype.GetContactList = function () { - return this.m_contactList; - } - b2Body.prototype.GetNext = function () { - return this.m_next; - } - b2Body.prototype.GetUserData = function () { - return this.m_userData; - } - b2Body.prototype.SetUserData = function (data) { - this.m_userData = data; - } - b2Body.prototype.GetWorld = function () { - return this.m_world; - } - b2Body.prototype.b2Body = function (bd, world) { - this.m_flags = 0; - if (bd.bullet) { - this.m_flags |= b2Body.e_bulletFlag; - } - if (bd.fixedRotation) { - this.m_flags |= b2Body.e_fixedRotationFlag; - } - if (bd.allowSleep) { - this.m_flags |= b2Body.e_allowSleepFlag; - } - if (bd.awake) { - this.m_flags |= b2Body.e_awakeFlag; - } - if (bd.active) { - this.m_flags |= b2Body.e_activeFlag; - } - this.m_world = world; - this.m_xf.position.SetV(bd.position); - this.m_xf.R.Set(bd.angle); - this.m_sweep.localCenter.SetZero(); - this.m_sweep.t0 = 1.0; - this.m_sweep.a0 = this.m_sweep.a = bd.angle; - var tMat = this.m_xf.R; - var tVec = this.m_sweep.localCenter; - this.m_sweep.c.x = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - this.m_sweep.c.y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - this.m_sweep.c.x += this.m_xf.position.x; - this.m_sweep.c.y += this.m_xf.position.y; - this.m_sweep.c0.SetV(this.m_sweep.c); - this.m_jointList = null; - this.m_controllerList = null; - this.m_contactList = null; - this.m_controllerCount = 0; - this.m_prev = null; - this.m_next = null; - this.m_linearVelocity.SetV(bd.linearVelocity); - this.m_angularVelocity = bd.angularVelocity; - this.m_linearDamping = bd.linearDamping; - this.m_angularDamping = bd.angularDamping; - this.m_force.Set(0.0, 0.0); - this.m_torque = 0.0; - this.m_sleepTime = 0.0; - this.m_type = bd.type; - if (this.m_type == b2Body.b2_dynamicBody) { - this.m_mass = 1.0; - this.m_invMass = 1.0; - } - else { - this.m_mass = 0.0; - this.m_invMass = 0.0; - } - this.m_I = 0.0; - this.m_invI = 0.0; - this.m_inertiaScale = bd.inertiaScale; - this.m_userData = bd.userData; - this.m_fixtureList = null; - this.m_fixtureCount = 0; - } - b2Body.prototype.SynchronizeFixtures = function () { - var xf1 = b2Body.s_xf1; - xf1.R.Set(this.m_sweep.a0); - var tMat = xf1.R; - var tVec = this.m_sweep.localCenter; - xf1.position.x = this.m_sweep.c0.x - (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - xf1.position.y = this.m_sweep.c0.y - (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - var f; - var broadPhase = this.m_world.m_contactManager.m_broadPhase; - for (f = this.m_fixtureList; - f; f = f.m_next) { - f.Synchronize(broadPhase, xf1, this.m_xf); - } - } - b2Body.prototype.SynchronizeTransform = function () { - this.m_xf.R.Set(this.m_sweep.a); - var tMat = this.m_xf.R; - var tVec = this.m_sweep.localCenter; - this.m_xf.position.x = this.m_sweep.c.x - (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - this.m_xf.position.y = this.m_sweep.c.y - (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - } - b2Body.prototype.ShouldCollide = function (other) { - if (this.m_type != b2Body.b2_dynamicBody && other.m_type != b2Body.b2_dynamicBody) { - return false; - } - for (var jn = this.m_jointList; jn; jn = jn.next) { - if (jn.other == other) if (jn.joint.m_collideConnected == false) { - return false; - } - } - return true; - } - b2Body.prototype.Advance = function (t) { - if (t === undefined) t = 0; - this.m_sweep.Advance(t); - this.m_sweep.c.SetV(this.m_sweep.c0); - this.m_sweep.a = this.m_sweep.a0; - this.SynchronizeTransform(); - } - Box2D.postDefs.push(function () { - Box2D.Dynamics.b2Body.s_xf1 = new b2Transform(); - Box2D.Dynamics.b2Body.e_islandFlag = 0x0001; - Box2D.Dynamics.b2Body.e_awakeFlag = 0x0002; - Box2D.Dynamics.b2Body.e_allowSleepFlag = 0x0004; - Box2D.Dynamics.b2Body.e_bulletFlag = 0x0008; - Box2D.Dynamics.b2Body.e_fixedRotationFlag = 0x0010; - Box2D.Dynamics.b2Body.e_activeFlag = 0x0020; - Box2D.Dynamics.b2Body.b2_staticBody = 0; - Box2D.Dynamics.b2Body.b2_kinematicBody = 1; - Box2D.Dynamics.b2Body.b2_dynamicBody = 2; - }); - b2BodyDef.b2BodyDef = function () { - this.position = new b2Vec2(); - this.linearVelocity = new b2Vec2(); - }; - b2BodyDef.prototype.b2BodyDef = function () { - this.userData = null; - this.position.Set(0.0, 0.0); - this.angle = 0.0; - this.linearVelocity.Set(0, 0); - this.angularVelocity = 0.0; - this.linearDamping = 0.0; - this.angularDamping = 0.0; - this.allowSleep = true; - this.awake = true; - this.fixedRotation = false; - this.bullet = false; - this.type = b2Body.b2_staticBody; - this.active = true; - this.inertiaScale = 1.0; - } - b2ContactFilter.b2ContactFilter = function () {}; - b2ContactFilter.prototype.ShouldCollide = function (fixtureA, fixtureB) { - var filter1 = fixtureA.GetFilterData(); - var filter2 = fixtureB.GetFilterData(); - if (filter1.groupIndex == filter2.groupIndex && filter1.groupIndex != 0) { - return filter1.groupIndex > 0; - } - var collide = (filter1.maskBits & filter2.categoryBits) != 0 && (filter1.categoryBits & filter2.maskBits) != 0; - return collide; - } - b2ContactFilter.prototype.RayCollide = function (userData, fixture) { - if (!userData) return true; - return this.ShouldCollide((userData instanceof b2Fixture ? userData : null), fixture); - } - Box2D.postDefs.push(function () { - Box2D.Dynamics.b2ContactFilter.b2_defaultFilter = new b2ContactFilter(); - }); - b2ContactImpulse.b2ContactImpulse = function () { - this.normalImpulses = new Vector_a2j_Number(b2Settings.b2_maxManifoldPoints); - this.tangentImpulses = new Vector_a2j_Number(b2Settings.b2_maxManifoldPoints); - }; - b2ContactListener.b2ContactListener = function () {}; - b2ContactListener.prototype.BeginContact = function (contact) {} - b2ContactListener.prototype.EndContact = function (contact) {} - b2ContactListener.prototype.PreSolve = function (contact, oldManifold) {} - b2ContactListener.prototype.PostSolve = function (contact, impulse) {} - Box2D.postDefs.push(function () { - Box2D.Dynamics.b2ContactListener.b2_defaultListener = new b2ContactListener(); - }); - b2ContactManager.b2ContactManager = function () {}; - b2ContactManager.prototype.b2ContactManager = function () { - this.m_world = null; - this.m_contactCount = 0; - this.m_contactFilter = b2ContactFilter.b2_defaultFilter; - this.m_contactListener = b2ContactListener.b2_defaultListener; - this.m_contactFactory = new b2ContactFactory(this.m_allocator); - this.m_broadPhase = new b2DynamicTreeBroadPhase(); - } - b2ContactManager.prototype.AddPair = function (proxyUserDataA, proxyUserDataB) { - var fixtureA = (proxyUserDataA instanceof b2Fixture ? proxyUserDataA : null); - var fixtureB = (proxyUserDataB instanceof b2Fixture ? proxyUserDataB : null); - var bodyA = fixtureA.GetBody(); - var bodyB = fixtureB.GetBody(); - if (bodyA == bodyB) return; - var edge = bodyB.GetContactList(); - while (edge) { - if (edge.other == bodyA) { - var fA = edge.contact.GetFixtureA(); - var fB = edge.contact.GetFixtureB(); - if (fA == fixtureA && fB == fixtureB) return; - if (fA == fixtureB && fB == fixtureA) return; - } - edge = edge.next; - } - if (bodyB.ShouldCollide(bodyA) == false) { - return; - } - if (this.m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false) { - return; - } - var c = this.m_contactFactory.Create(fixtureA, fixtureB); - fixtureA = c.GetFixtureA(); - fixtureB = c.GetFixtureB(); - bodyA = fixtureA.m_body; - bodyB = fixtureB.m_body; - c.m_prev = null; - c.m_next = this.m_world.m_contactList; - if (this.m_world.m_contactList != null) { - this.m_world.m_contactList.m_prev = c; - } - this.m_world.m_contactList = c; - c.m_nodeA.contact = c; - c.m_nodeA.other = bodyB; - c.m_nodeA.prev = null; - c.m_nodeA.next = bodyA.m_contactList; - if (bodyA.m_contactList != null) { - bodyA.m_contactList.prev = c.m_nodeA; - } - bodyA.m_contactList = c.m_nodeA; - c.m_nodeB.contact = c; - c.m_nodeB.other = bodyA; - c.m_nodeB.prev = null; - c.m_nodeB.next = bodyB.m_contactList; - if (bodyB.m_contactList != null) { - bodyB.m_contactList.prev = c.m_nodeB; - } - bodyB.m_contactList = c.m_nodeB; - ++this.m_world.m_contactCount; - return; - } - b2ContactManager.prototype.FindNewContacts = function () { - this.m_broadPhase.UpdatePairs(Box2D.generateCallback(this, this.AddPair)); - } - b2ContactManager.prototype.Destroy = function (c) { - var fixtureA = c.GetFixtureA(); - var fixtureB = c.GetFixtureB(); - var bodyA = fixtureA.GetBody(); - var bodyB = fixtureB.GetBody(); - if (c.IsTouching()) { - this.m_contactListener.EndContact(c); - } - if (c.m_prev) { - c.m_prev.m_next = c.m_next; - } - if (c.m_next) { - c.m_next.m_prev = c.m_prev; - } - if (c == this.m_world.m_contactList) { - this.m_world.m_contactList = c.m_next; - } - if (c.m_nodeA.prev) { - c.m_nodeA.prev.next = c.m_nodeA.next; - } - if (c.m_nodeA.next) { - c.m_nodeA.next.prev = c.m_nodeA.prev; - } - if (c.m_nodeA == bodyA.m_contactList) { - bodyA.m_contactList = c.m_nodeA.next; - } - if (c.m_nodeB.prev) { - c.m_nodeB.prev.next = c.m_nodeB.next; - } - if (c.m_nodeB.next) { - c.m_nodeB.next.prev = c.m_nodeB.prev; - } - if (c.m_nodeB == bodyB.m_contactList) { - bodyB.m_contactList = c.m_nodeB.next; - } - this.m_contactFactory.Destroy(c); - --this.m_contactCount; - } - b2ContactManager.prototype.Collide = function () { - var c = this.m_world.m_contactList; - while (c) { - var fixtureA = c.GetFixtureA(); - var fixtureB = c.GetFixtureB(); - var bodyA = fixtureA.GetBody(); - var bodyB = fixtureB.GetBody(); - if (bodyA.IsAwake() == false && bodyB.IsAwake() == false) { - c = c.GetNext(); - continue; - } - if (c.m_flags & b2Contact.e_filterFlag) { - if (bodyB.ShouldCollide(bodyA) == false) { - var cNuke = c; - c = cNuke.GetNext(); - this.Destroy(cNuke); - continue; - } - if (this.m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false) { - cNuke = c; - c = cNuke.GetNext(); - this.Destroy(cNuke); - continue; - } - c.m_flags &= ~b2Contact.e_filterFlag; - } - var proxyA = fixtureA.m_proxy; - var proxyB = fixtureB.m_proxy; - var overlap = this.m_broadPhase.TestOverlap(proxyA, proxyB); - if (overlap == false) { - cNuke = c; - c = cNuke.GetNext(); - this.Destroy(cNuke); - continue; - } - c.Update(this.m_contactListener); - c = c.GetNext(); - } - } - Box2D.postDefs.push(function () { - Box2D.Dynamics.b2ContactManager.s_evalCP = new b2ContactPoint(); - }); - b2DebugDraw.b2DebugDraw = function () {}; - b2DebugDraw.prototype.b2DebugDraw = function () {} - b2DebugDraw.prototype.SetFlags = function (flags) { - if (flags === undefined) flags = 0; - } - b2DebugDraw.prototype.GetFlags = function () {} - b2DebugDraw.prototype.AppendFlags = function (flags) { - if (flags === undefined) flags = 0; - } - b2DebugDraw.prototype.ClearFlags = function (flags) { - if (flags === undefined) flags = 0; - } - b2DebugDraw.prototype.SetSprite = function (sprite) {} - b2DebugDraw.prototype.GetSprite = function () {} - b2DebugDraw.prototype.SetDrawScale = function (drawScale) { - if (drawScale === undefined) drawScale = 0; - } - b2DebugDraw.prototype.GetDrawScale = function () {} - b2DebugDraw.prototype.SetLineThickness = function (lineThickness) { - if (lineThickness === undefined) lineThickness = 0; - } - b2DebugDraw.prototype.GetLineThickness = function () {} - b2DebugDraw.prototype.SetAlpha = function (alpha) { - if (alpha === undefined) alpha = 0; - } - b2DebugDraw.prototype.GetAlpha = function () {} - b2DebugDraw.prototype.SetFillAlpha = function (alpha) { - if (alpha === undefined) alpha = 0; - } - b2DebugDraw.prototype.GetFillAlpha = function () {} - b2DebugDraw.prototype.SetXFormScale = function (xformScale) { - if (xformScale === undefined) xformScale = 0; - } - b2DebugDraw.prototype.GetXFormScale = function () {} - b2DebugDraw.prototype.DrawPolygon = function (vertices, vertexCount, color) { - if (vertexCount === undefined) vertexCount = 0; - } - b2DebugDraw.prototype.DrawSolidPolygon = function (vertices, vertexCount, color) { - if (vertexCount === undefined) vertexCount = 0; - } - b2DebugDraw.prototype.DrawCircle = function (center, radius, color) { - if (radius === undefined) radius = 0; - } - b2DebugDraw.prototype.DrawSolidCircle = function (center, radius, axis, color) { - if (radius === undefined) radius = 0; - } - b2DebugDraw.prototype.DrawSegment = function (p1, p2, color) {} - b2DebugDraw.prototype.DrawTransform = function (xf) {} - Box2D.postDefs.push(function () { - Box2D.Dynamics.b2DebugDraw.e_shapeBit = 0x0001; - Box2D.Dynamics.b2DebugDraw.e_jointBit = 0x0002; - Box2D.Dynamics.b2DebugDraw.e_aabbBit = 0x0004; - Box2D.Dynamics.b2DebugDraw.e_pairBit = 0x0008; - Box2D.Dynamics.b2DebugDraw.e_centerOfMassBit = 0x0010; - Box2D.Dynamics.b2DebugDraw.e_controllerBit = 0x0020; - }); - b2DestructionListener.b2DestructionListener = function () {}; - b2DestructionListener.prototype.SayGoodbyeJoint = function (joint) {} - b2DestructionListener.prototype.SayGoodbyeFixture = function (fixture) {} - b2FilterData.b2FilterData = function () { - this.categoryBits = 0x0001; - this.maskBits = 0xFFFF; - this.groupIndex = 0; - }; - b2FilterData.prototype.Copy = function () { - var copy = new b2FilterData(); - copy.categoryBits = this.categoryBits; - copy.maskBits = this.maskBits; - copy.groupIndex = this.groupIndex; - return copy; - } - b2Fixture.b2Fixture = function () { - this.m_filter = new b2FilterData(); - }; - b2Fixture.prototype.GetType = function () { - return this.m_shape.GetType(); - } - b2Fixture.prototype.GetShape = function () { - return this.m_shape; - } - b2Fixture.prototype.SetSensor = function (sensor) { - if (this.m_isSensor == sensor) return; - this.m_isSensor = sensor; - if (this.m_body == null) return; - var edge = this.m_body.GetContactList(); - while (edge) { - var contact = edge.contact; - var fixtureA = contact.GetFixtureA(); - var fixtureB = contact.GetFixtureB(); - if (fixtureA == this || fixtureB == this) contact.SetSensor(fixtureA.IsSensor() || fixtureB.IsSensor()); - edge = edge.next; - } - } - b2Fixture.prototype.IsSensor = function () { - return this.m_isSensor; - } - b2Fixture.prototype.SetFilterData = function (filter) { - this.m_filter = filter.Copy(); - if (this.m_body) return; - var edge = this.m_body.GetContactList(); - while (edge) { - var contact = edge.contact; - var fixtureA = contact.GetFixtureA(); - var fixtureB = contact.GetFixtureB(); - if (fixtureA == this || fixtureB == this) contact.FlagForFiltering(); - edge = edge.next; - } - } - b2Fixture.prototype.GetFilterData = function () { - return this.m_filter.Copy(); - } - b2Fixture.prototype.GetBody = function () { - return this.m_body; - } - b2Fixture.prototype.GetNext = function () { - return this.m_next; - } - b2Fixture.prototype.GetUserData = function () { - return this.m_userData; - } - b2Fixture.prototype.SetUserData = function (data) { - this.m_userData = data; - } - b2Fixture.prototype.TestPoint = function (p) { - return this.m_shape.TestPoint(this.m_body.GetTransform(), p); - } - b2Fixture.prototype.RayCast = function (output, input) { - return this.m_shape.RayCast(output, input, this.m_body.GetTransform()); - } - b2Fixture.prototype.GetMassData = function (massData) { - if (massData === undefined) massData = null; - if (massData == null) { - massData = new b2MassData(); - } - this.m_shape.ComputeMass(massData, this.m_density); - return massData; - } - b2Fixture.prototype.SetDensity = function (density) { - if (density === undefined) density = 0; - this.m_density = density; - } - b2Fixture.prototype.GetDensity = function () { - return this.m_density; - } - b2Fixture.prototype.GetFriction = function () { - return this.m_friction; - } - b2Fixture.prototype.SetFriction = function (friction) { - if (friction === undefined) friction = 0; - this.m_friction = friction; - } - b2Fixture.prototype.GetRestitution = function () { - return this.m_restitution; - } - b2Fixture.prototype.SetRestitution = function (restitution) { - if (restitution === undefined) restitution = 0; - this.m_restitution = restitution; - } - b2Fixture.prototype.GetAABB = function () { - return this.m_aabb; - } - b2Fixture.prototype.b2Fixture = function () { - this.m_aabb = new b2AABB(); - this.m_userData = null; - this.m_body = null; - this.m_next = null; - this.m_shape = null; - this.m_density = 0.0; - this.m_friction = 0.0; - this.m_restitution = 0.0; - } - b2Fixture.prototype.Create = function (body, xf, def) { - this.m_userData = def.userData; - this.m_friction = def.friction; - this.m_restitution = def.restitution; - this.m_body = body; - this.m_next = null; - this.m_filter = def.filter.Copy(); - this.m_isSensor = def.isSensor; - this.m_shape = def.shape.Copy(); - this.m_density = def.density; - } - b2Fixture.prototype.Destroy = function () { - this.m_shape = null; - } - b2Fixture.prototype.CreateProxy = function (broadPhase, xf) { - this.m_shape.ComputeAABB(this.m_aabb, xf); - this.m_proxy = broadPhase.CreateProxy(this.m_aabb, this); - } - b2Fixture.prototype.DestroyProxy = function (broadPhase) { - if (this.m_proxy == null) { - return; - } - broadPhase.DestroyProxy(this.m_proxy); - this.m_proxy = null; - } - b2Fixture.prototype.Synchronize = function (broadPhase, transform1, transform2) { - if (!this.m_proxy) return; - var aabb1 = new b2AABB(); - var aabb2 = new b2AABB(); - this.m_shape.ComputeAABB(aabb1, transform1); - this.m_shape.ComputeAABB(aabb2, transform2); - this.m_aabb.Combine(aabb1, aabb2); - var displacement = b2Math.SubtractVV(transform2.position, transform1.position); - broadPhase.MoveProxy(this.m_proxy, this.m_aabb, displacement); - } - b2FixtureDef.b2FixtureDef = function () { - this.filter = new b2FilterData(); - }; - b2FixtureDef.prototype.b2FixtureDef = function () { - this.shape = null; - this.userData = null; - this.friction = 0.2; - this.restitution = 0.0; - this.density = 0.0; - this.filter.categoryBits = 0x0001; - this.filter.maskBits = 0xFFFF; - this.filter.groupIndex = 0; - this.isSensor = false; - } - b2Island.b2Island = function () {}; - b2Island.prototype.b2Island = function () { - this.m_bodies = new Vector(); - this.m_contacts = new Vector(); - this.m_joints = new Vector(); - } - b2Island.prototype.Initialize = function (bodyCapacity, contactCapacity, jointCapacity, allocator, listener, contactSolver) { - if (bodyCapacity === undefined) bodyCapacity = 0; - if (contactCapacity === undefined) contactCapacity = 0; - if (jointCapacity === undefined) jointCapacity = 0; - var i = 0; - this.m_bodyCapacity = bodyCapacity; - this.m_contactCapacity = contactCapacity; - this.m_jointCapacity = jointCapacity; - this.m_bodyCount = 0; - this.m_contactCount = 0; - this.m_jointCount = 0; - this.m_allocator = allocator; - this.m_listener = listener; - this.m_contactSolver = contactSolver; - for (i = this.m_bodies.length; - i < bodyCapacity; i++) - this.m_bodies[i] = null; - for (i = this.m_contacts.length; - i < contactCapacity; i++) - this.m_contacts[i] = null; - for (i = this.m_joints.length; - i < jointCapacity; i++) - this.m_joints[i] = null; - } - b2Island.prototype.Clear = function () { - this.m_bodyCount = 0; - this.m_contactCount = 0; - this.m_jointCount = 0; - } - b2Island.prototype.Solve = function (step, gravity, allowSleep) { - var i = 0; - var j = 0; - var b; - var joint; - for (i = 0; - i < this.m_bodyCount; ++i) { - b = this.m_bodies[i]; - if (b.GetType() != b2Body.b2_dynamicBody) continue; - b.m_linearVelocity.x += step.dt * (gravity.x + b.m_invMass * b.m_force.x); - b.m_linearVelocity.y += step.dt * (gravity.y + b.m_invMass * b.m_force.y); - b.m_angularVelocity += step.dt * b.m_invI * b.m_torque; - b.m_linearVelocity.Multiply(b2Math.Clamp(1.0 - step.dt * b.m_linearDamping, 0.0, 1.0)); - b.m_angularVelocity *= b2Math.Clamp(1.0 - step.dt * b.m_angularDamping, 0.0, 1.0); - } - this.m_contactSolver.Initialize(step, this.m_contacts, this.m_contactCount, this.m_allocator); - var contactSolver = this.m_contactSolver; - contactSolver.InitVelocityConstraints(step); - for (i = 0; - i < this.m_jointCount; ++i) { - joint = this.m_joints[i]; - joint.InitVelocityConstraints(step); - } - for (i = 0; - i < step.velocityIterations; ++i) { - for (j = 0; - j < this.m_jointCount; ++j) { - joint = this.m_joints[j]; - joint.SolveVelocityConstraints(step); - } - contactSolver.SolveVelocityConstraints(); - } - for (i = 0; - i < this.m_jointCount; ++i) { - joint = this.m_joints[i]; - joint.FinalizeVelocityConstraints(); - } - contactSolver.FinalizeVelocityConstraints(); - for (i = 0; - i < this.m_bodyCount; ++i) { - b = this.m_bodies[i]; - if (b.GetType() == b2Body.b2_staticBody) continue; - var translationX = step.dt * b.m_linearVelocity.x; - var translationY = step.dt * b.m_linearVelocity.y; - if ((translationX * translationX + translationY * translationY) > b2Settings.b2_maxTranslationSquared) { - b.m_linearVelocity.Normalize(); - b.m_linearVelocity.x *= b2Settings.b2_maxTranslation * step.inv_dt; - b.m_linearVelocity.y *= b2Settings.b2_maxTranslation * step.inv_dt; - } - var rotation = step.dt * b.m_angularVelocity; - if (rotation * rotation > b2Settings.b2_maxRotationSquared) { - if (b.m_angularVelocity < 0.0) { - b.m_angularVelocity = (-b2Settings.b2_maxRotation * step.inv_dt); - } - else { - b.m_angularVelocity = b2Settings.b2_maxRotation * step.inv_dt; - } - } - b.m_sweep.c0.SetV(b.m_sweep.c); - b.m_sweep.a0 = b.m_sweep.a; - b.m_sweep.c.x += step.dt * b.m_linearVelocity.x; - b.m_sweep.c.y += step.dt * b.m_linearVelocity.y; - b.m_sweep.a += step.dt * b.m_angularVelocity; - b.SynchronizeTransform(); - } - for (i = 0; - i < step.positionIterations; ++i) { - var contactsOkay = contactSolver.SolvePositionConstraints(b2Settings.b2_contactBaumgarte); - var jointsOkay = true; - for (j = 0; - j < this.m_jointCount; ++j) { - joint = this.m_joints[j]; - var jointOkay = joint.SolvePositionConstraints(b2Settings.b2_contactBaumgarte); - jointsOkay = jointsOkay && jointOkay; - } - if (contactsOkay && jointsOkay) { - break; - } - } - this.Report(contactSolver.m_constraints); - if (allowSleep) { - var minSleepTime = Number.MAX_VALUE; - var linTolSqr = b2Settings.b2_linearSleepTolerance * b2Settings.b2_linearSleepTolerance; - var angTolSqr = b2Settings.b2_angularSleepTolerance * b2Settings.b2_angularSleepTolerance; - for (i = 0; - i < this.m_bodyCount; ++i) { - b = this.m_bodies[i]; - if (b.GetType() == b2Body.b2_staticBody) { - continue; - } - if ((b.m_flags & b2Body.e_allowSleepFlag) == 0) { - b.m_sleepTime = 0.0; - minSleepTime = 0.0; - } - if ((b.m_flags & b2Body.e_allowSleepFlag) == 0 || b.m_angularVelocity * b.m_angularVelocity > angTolSqr || b2Math.Dot(b.m_linearVelocity, b.m_linearVelocity) > linTolSqr) { - b.m_sleepTime = 0.0; - minSleepTime = 0.0; - } - else { - b.m_sleepTime += step.dt; - minSleepTime = b2Math.Min(minSleepTime, b.m_sleepTime); - } - } - if (minSleepTime >= b2Settings.b2_timeToSleep) { - for (i = 0; - i < this.m_bodyCount; ++i) { - b = this.m_bodies[i]; - b.SetAwake(false); - } - } - } - } - b2Island.prototype.SolveTOI = function (subStep) { - var i = 0; - var j = 0; - this.m_contactSolver.Initialize(subStep, this.m_contacts, this.m_contactCount, this.m_allocator); - var contactSolver = this.m_contactSolver; - for (i = 0; - i < this.m_jointCount; ++i) { - this.m_joints[i].InitVelocityConstraints(subStep); - } - for (i = 0; - i < subStep.velocityIterations; ++i) { - contactSolver.SolveVelocityConstraints(); - for (j = 0; - j < this.m_jointCount; ++j) { - this.m_joints[j].SolveVelocityConstraints(subStep); - } - } - for (i = 0; - i < this.m_bodyCount; ++i) { - var b = this.m_bodies[i]; - if (b.GetType() == b2Body.b2_staticBody) continue; - var translationX = subStep.dt * b.m_linearVelocity.x; - var translationY = subStep.dt * b.m_linearVelocity.y; - if ((translationX * translationX + translationY * translationY) > b2Settings.b2_maxTranslationSquared) { - b.m_linearVelocity.Normalize(); - b.m_linearVelocity.x *= b2Settings.b2_maxTranslation * subStep.inv_dt; - b.m_linearVelocity.y *= b2Settings.b2_maxTranslation * subStep.inv_dt; - } - var rotation = subStep.dt * b.m_angularVelocity; - if (rotation * rotation > b2Settings.b2_maxRotationSquared) { - if (b.m_angularVelocity < 0.0) { - b.m_angularVelocity = (-b2Settings.b2_maxRotation * subStep.inv_dt); - } - else { - b.m_angularVelocity = b2Settings.b2_maxRotation * subStep.inv_dt; - } - } - b.m_sweep.c0.SetV(b.m_sweep.c); - b.m_sweep.a0 = b.m_sweep.a; - b.m_sweep.c.x += subStep.dt * b.m_linearVelocity.x; - b.m_sweep.c.y += subStep.dt * b.m_linearVelocity.y; - b.m_sweep.a += subStep.dt * b.m_angularVelocity; - b.SynchronizeTransform(); - } - var k_toiBaumgarte = 0.75; - for (i = 0; - i < subStep.positionIterations; ++i) { - var contactsOkay = contactSolver.SolvePositionConstraints(k_toiBaumgarte); - var jointsOkay = true; - for (j = 0; - j < this.m_jointCount; ++j) { - var jointOkay = this.m_joints[j].SolvePositionConstraints(b2Settings.b2_contactBaumgarte); - jointsOkay = jointsOkay && jointOkay; - } - if (contactsOkay && jointsOkay) { - break; - } - } - this.Report(contactSolver.m_constraints); - } - b2Island.prototype.Report = function (constraints) { - if (this.m_listener == null) { - return; - } - for (var i = 0; i < this.m_contactCount; ++i) { - var c = this.m_contacts[i]; - var cc = constraints[i]; - for (var j = 0; j < cc.pointCount; ++j) { - b2Island.s_impulse.normalImpulses[j] = cc.points[j].normalImpulse; - b2Island.s_impulse.tangentImpulses[j] = cc.points[j].tangentImpulse; - } - this.m_listener.PostSolve(c, b2Island.s_impulse); - } - } - b2Island.prototype.AddBody = function (body) { - body.m_islandIndex = this.m_bodyCount; - this.m_bodies[this.m_bodyCount++] = body; - } - b2Island.prototype.AddContact = function (contact) { - this.m_contacts[this.m_contactCount++] = contact; - } - b2Island.prototype.AddJoint = function (joint) { - this.m_joints[this.m_jointCount++] = joint; - } - Box2D.postDefs.push(function () { - Box2D.Dynamics.b2Island.s_impulse = new b2ContactImpulse(); - }); - b2TimeStep.b2TimeStep = function () {}; - b2TimeStep.prototype.Set = function (step) { - this.dt = step.dt; - this.inv_dt = step.inv_dt; - this.positionIterations = step.positionIterations; - this.velocityIterations = step.velocityIterations; - this.warmStarting = step.warmStarting; - } - b2World.b2World = function () { - this.s_stack = new Vector(); - this.m_contactManager = new b2ContactManager(); - this.m_contactSolver = new b2ContactSolver(); - this.m_island = new b2Island(); - }; - b2World.prototype.b2World = function (gravity, doSleep) { - this.m_destructionListener = null; - this.m_debugDraw = null; - this.m_bodyList = null; - this.m_contactList = null; - this.m_jointList = null; - this.m_controllerList = null; - this.m_bodyCount = 0; - this.m_contactCount = 0; - this.m_jointCount = 0; - this.m_controllerCount = 0; - b2World.m_warmStarting = true; - b2World.m_continuousPhysics = true; - this.m_allowSleep = doSleep; - gravity.y = gravity.y; - this.m_gravity = gravity; - this.m_inv_dt0 = 0.0; - this.m_contactManager.m_world = this; - var bd = new b2BodyDef(); - this.m_groundBody = this.CreateBody(bd); - } - b2World.prototype.SetDestructionListener = function (listener) { - this.m_destructionListener = listener; - } - b2World.prototype.SetContactFilter = function (filter) { - this.m_contactManager.m_contactFilter = filter; - } - b2World.prototype.SetContactListener = function (listener) { - this.m_contactManager.m_contactListener = listener; - } - b2World.prototype.SetDebugDraw = function (debugDraw) { - this.m_debugDraw = debugDraw; - } - b2World.prototype.SetBroadPhase = function (broadPhase) { - var oldBroadPhase = this.m_contactManager.m_broadPhase; - this.m_contactManager.m_broadPhase = broadPhase; - for (var b = this.m_bodyList; b; b = b.m_next) { - for (var f = b.m_fixtureList; f; f = f.m_next) { - f.m_proxy = broadPhase.CreateProxy(oldBroadPhase.GetFatAABB(f.m_proxy), f); - } - } - } - b2World.prototype.Validate = function () { - this.m_contactManager.m_broadPhase.Validate(); - } - b2World.prototype.GetProxyCount = function () { - return this.m_contactManager.m_broadPhase.GetProxyCount(); - } - b2World.prototype.CreateBody = function (def) { - if (this.IsLocked() == true) { - return null; - } - var b = new b2Body(def, this); - b.m_prev = null; - b.m_next = this.m_bodyList; - if (this.m_bodyList) { - this.m_bodyList.m_prev = b; - } - this.m_bodyList = b; - ++this.m_bodyCount; - return b; - } - b2World.prototype.DestroyBody = function (b) { - if (this.IsLocked() == true) { - return; - } - var jn = b.m_jointList; - while (jn) { - var jn0 = jn; - jn = jn.next; - if (this.m_destructionListener) { - this.m_destructionListener.SayGoodbyeJoint(jn0.joint); - } - this.DestroyJoint(jn0.joint); - } - var coe = b.m_controllerList; - while (coe) { - var coe0 = coe; - coe = coe.nextController; - coe0.controller.RemoveBody(b); - } - var ce = b.m_contactList; - while (ce) { - var ce0 = ce; - ce = ce.next; - this.m_contactManager.Destroy(ce0.contact); - } - b.m_contactList = null; - var f = b.m_fixtureList; - while (f) { - var f0 = f; - f = f.m_next; - if (this.m_destructionListener) { - this.m_destructionListener.SayGoodbyeFixture(f0); - } - f0.DestroyProxy(this.m_contactManager.m_broadPhase); - f0.Destroy(); - } - b.m_fixtureList = null; - b.m_fixtureCount = 0; - if (b.m_prev) { - b.m_prev.m_next = b.m_next; - } - if (b.m_next) { - b.m_next.m_prev = b.m_prev; - } - if (b == this.m_bodyList) { - this.m_bodyList = b.m_next; - }--this.m_bodyCount; - } - b2World.prototype.CreateJoint = function (def) { - var j = b2Joint.Create(def, null); - j.m_prev = null; - j.m_next = this.m_jointList; - if (this.m_jointList) { - this.m_jointList.m_prev = j; - } - this.m_jointList = j; - ++this.m_jointCount; - j.m_edgeA.joint = j; - j.m_edgeA.other = j.m_bodyB; - j.m_edgeA.prev = null; - j.m_edgeA.next = j.m_bodyA.m_jointList; - if (j.m_bodyA.m_jointList) j.m_bodyA.m_jointList.prev = j.m_edgeA; - j.m_bodyA.m_jointList = j.m_edgeA; - j.m_edgeB.joint = j; - j.m_edgeB.other = j.m_bodyA; - j.m_edgeB.prev = null; - j.m_edgeB.next = j.m_bodyB.m_jointList; - if (j.m_bodyB.m_jointList) j.m_bodyB.m_jointList.prev = j.m_edgeB; - j.m_bodyB.m_jointList = j.m_edgeB; - var bodyA = def.bodyA; - var bodyB = def.bodyB; - if (def.collideConnected == false) { - var edge = bodyB.GetContactList(); - while (edge) { - if (edge.other == bodyA) { - edge.contact.FlagForFiltering(); - } - edge = edge.next; - } - } - return j; - } - b2World.prototype.DestroyJoint = function (j) { - var collideConnected = j.m_collideConnected; - if (j.m_prev) { - j.m_prev.m_next = j.m_next; - } - if (j.m_next) { - j.m_next.m_prev = j.m_prev; - } - if (j == this.m_jointList) { - this.m_jointList = j.m_next; - } - var bodyA = j.m_bodyA; - var bodyB = j.m_bodyB; - bodyA.SetAwake(true); - bodyB.SetAwake(true); - if (j.m_edgeA.prev) { - j.m_edgeA.prev.next = j.m_edgeA.next; - } - if (j.m_edgeA.next) { - j.m_edgeA.next.prev = j.m_edgeA.prev; - } - if (j.m_edgeA == bodyA.m_jointList) { - bodyA.m_jointList = j.m_edgeA.next; - } - j.m_edgeA.prev = null; - j.m_edgeA.next = null; - if (j.m_edgeB.prev) { - j.m_edgeB.prev.next = j.m_edgeB.next; - } - if (j.m_edgeB.next) { - j.m_edgeB.next.prev = j.m_edgeB.prev; - } - if (j.m_edgeB == bodyB.m_jointList) { - bodyB.m_jointList = j.m_edgeB.next; - } - j.m_edgeB.prev = null; - j.m_edgeB.next = null; - b2Joint.Destroy(j, null); - --this.m_jointCount; - if (collideConnected == false) { - var edge = bodyB.GetContactList(); - while (edge) { - if (edge.other == bodyA) { - edge.contact.FlagForFiltering(); - } - edge = edge.next; - } - } - } - b2World.prototype.AddController = function (c) { - c.m_next = this.m_controllerList; - c.m_prev = null; - this.m_controllerList = c; - c.m_world = this; - this.m_controllerCount++; - return c; - } - b2World.prototype.RemoveController = function (c) { - if (c.m_prev) c.m_prev.m_next = c.m_next; - if (c.m_next) c.m_next.m_prev = c.m_prev; - if (this.m_controllerList == c) this.m_controllerList = c.m_next; - this.m_controllerCount--; - } - b2World.prototype.CreateController = function (controller) { - if (controller.m_world != this) throw new Error("Controller can only be a member of one world"); - controller.m_next = this.m_controllerList; - controller.m_prev = null; - if (this.m_controllerList) this.m_controllerList.m_prev = controller; - this.m_controllerList = controller; - ++this.m_controllerCount; - controller.m_world = this; - return controller; - } - b2World.prototype.DestroyController = function (controller) { - controller.Clear(); - if (controller.m_next) controller.m_next.m_prev = controller.m_prev; - if (controller.m_prev) controller.m_prev.m_next = controller.m_next; - if (controller == this.m_controllerList) this.m_controllerList = controller.m_next; - --this.m_controllerCount; - } - b2World.prototype.SetWarmStarting = function (flag) { - b2World.m_warmStarting = flag; - } - b2World.prototype.SetContinuousPhysics = function (flag) { - b2World.m_continuousPhysics = flag; - } - b2World.prototype.GetBodyCount = function () { - return this.m_bodyCount; - } - b2World.prototype.GetJointCount = function () { - return this.m_jointCount; - } - b2World.prototype.GetContactCount = function () { - return this.m_contactCount; - } - b2World.prototype.SetGravity = function (gravity) { - this.m_gravity = gravity; - } - b2World.prototype.GetGravity = function () { - return this.m_gravity; - } - b2World.prototype.GetGroundBody = function () { - return this.m_groundBody; - } - b2World.prototype.Step = function (dt, velocityIterations, positionIterations) { - if (dt === undefined) dt = 0; - if (velocityIterations === undefined) velocityIterations = 0; - if (positionIterations === undefined) positionIterations = 0; - if (this.m_flags & b2World.e_newFixture) { - this.m_contactManager.FindNewContacts(); - this.m_flags &= ~b2World.e_newFixture; - } - this.m_flags |= b2World.e_locked; - var step = b2World.s_timestep2; - step.dt = dt; - step.velocityIterations = velocityIterations; - step.positionIterations = positionIterations; - if (dt > 0.0) { - step.inv_dt = 1.0 / dt; - } - else { - step.inv_dt = 0.0; - } - step.dtRatio = this.m_inv_dt0 * dt; - step.warmStarting = b2World.m_warmStarting; - this.m_contactManager.Collide(); - if (step.dt > 0.0) { - this.Solve(step); - } - if (b2World.m_continuousPhysics && step.dt > 0.0) { - this.SolveTOI(step); - } - if (step.dt > 0.0) { - this.m_inv_dt0 = step.inv_dt; - } - this.m_flags &= ~b2World.e_locked; - } - b2World.prototype.ClearForces = function () { - for (var body = this.m_bodyList; body; body = body.m_next) { - body.m_force.SetZero(); - body.m_torque = 0.0; - } - } - b2World.prototype.DrawDebugData = function () { - if (this.m_debugDraw == null) { - return; - } - this.m_debugDraw.m_sprite.graphics.clear(); - var flags = this.m_debugDraw.GetFlags(); - var i = 0; - var b; - var f; - var s; - var j; - var bp; - var invQ = new b2Vec2; - var x1 = new b2Vec2; - var x2 = new b2Vec2; - var xf; - var b1 = new b2AABB(); - var b2 = new b2AABB(); - var vs = [new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Vec2()]; - var color = new b2Color(0, 0, 0); - if (flags & b2DebugDraw.e_shapeBit) { - for (b = this.m_bodyList; - b; b = b.m_next) { - xf = b.m_xf; - for (f = b.GetFixtureList(); - f; f = f.m_next) { - s = f.GetShape(); - if (b.IsActive() == false) { - color.Set(0.5, 0.5, 0.3); - this.DrawShape(s, xf, color); - } - else if (b.GetType() == b2Body.b2_staticBody) { - color.Set(0.5, 0.9, 0.5); - this.DrawShape(s, xf, color); - } - else if (b.GetType() == b2Body.b2_kinematicBody) { - color.Set(0.5, 0.5, 0.9); - this.DrawShape(s, xf, color); - } - else if (b.IsAwake() == false) { - color.Set(0.6, 0.6, 0.6); - this.DrawShape(s, xf, color); - } - else { - color.Set(0.9, 0.7, 0.7); - this.DrawShape(s, xf, color); - } - } - } - } - if (flags & b2DebugDraw.e_jointBit) { - for (j = this.m_jointList; - j; j = j.m_next) { - this.DrawJoint(j); - } - } - if (flags & b2DebugDraw.e_controllerBit) { - for (var c = this.m_controllerList; c; c = c.m_next) { - c.Draw(this.m_debugDraw); - } - } - if (flags & b2DebugDraw.e_pairBit) { - color.Set(0.3, 0.9, 0.9); - for (var contact = this.m_contactManager.m_contactList; contact; contact = contact.GetNext()) { - var fixtureA = contact.GetFixtureA(); - var fixtureB = contact.GetFixtureB(); - var cA = fixtureA.GetAABB().GetCenter(); - var cB = fixtureB.GetAABB().GetCenter(); - this.m_debugDraw.DrawSegment(cA, cB, color); - } - } - if (flags & b2DebugDraw.e_aabbBit) { - bp = this.m_contactManager.m_broadPhase; - vs = [new b2Vec2(), new b2Vec2(), new b2Vec2(), new b2Vec2()]; - for (b = this.m_bodyList; - b; b = b.GetNext()) { - if (b.IsActive() == false) { - continue; - } - for (f = b.GetFixtureList(); - f; f = f.GetNext()) { - var aabb = bp.GetFatAABB(f.m_proxy); - vs[0].Set(aabb.lowerBound.x, aabb.lowerBound.y); - vs[1].Set(aabb.upperBound.x, aabb.lowerBound.y); - vs[2].Set(aabb.upperBound.x, aabb.upperBound.y); - vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y); - this.m_debugDraw.DrawPolygon(vs, 4, color); - } - } - } - if (flags & b2DebugDraw.e_centerOfMassBit) { - for (b = this.m_bodyList; - b; b = b.m_next) { - xf = b2World.s_xf; - xf.R = b.m_xf.R; - xf.position = b.GetWorldCenter(); - this.m_debugDraw.DrawTransform(xf); - } - } - } - b2World.prototype.QueryAABB = function (callback, aabb) { - var __this = this; - var broadPhase = __this.m_contactManager.m_broadPhase; - - function WorldQueryWrapper(proxy) { - return callback(broadPhase.GetUserData(proxy)); - }; - broadPhase.Query(WorldQueryWrapper, aabb); - } - b2World.prototype.QueryShape = function (callback, shape, transform) { - var __this = this; - if (transform === undefined) transform = null; - if (transform == null) { - transform = new b2Transform(); - transform.SetIdentity(); - } - var broadPhase = __this.m_contactManager.m_broadPhase; - - function WorldQueryWrapper(proxy) { - var fixture = (broadPhase.GetUserData(proxy) instanceof b2Fixture ? broadPhase.GetUserData(proxy) : null); - if (b2Shape.TestOverlap(shape, transform, fixture.GetShape(), fixture.GetBody().GetTransform())) return callback(fixture); - return true; - }; - var aabb = new b2AABB(); - shape.ComputeAABB(aabb, transform); - broadPhase.Query(WorldQueryWrapper, aabb); - } - b2World.prototype.QueryPoint = function (callback, p) { - var __this = this; - var broadPhase = __this.m_contactManager.m_broadPhase; - - function WorldQueryWrapper(proxy) { - var fixture = (broadPhase.GetUserData(proxy) instanceof b2Fixture ? broadPhase.GetUserData(proxy) : null); - if (fixture.TestPoint(p)) return callback(fixture); - return true; - }; - var aabb = new b2AABB(); - aabb.lowerBound.Set(p.x - b2Settings.b2_linearSlop, p.y - b2Settings.b2_linearSlop); - aabb.upperBound.Set(p.x + b2Settings.b2_linearSlop, p.y + b2Settings.b2_linearSlop); - broadPhase.Query(WorldQueryWrapper, aabb); - } - b2World.prototype.RayCast = function (callback, point1, point2) { - var __this = this; - var broadPhase = __this.m_contactManager.m_broadPhase; - var output = new b2RayCastOutput; - - function RayCastWrapper(input, proxy) { - var userData = broadPhase.GetUserData(proxy); - var fixture = (userData instanceof b2Fixture ? userData : null); - var hit = fixture.RayCast(output, input); - if (hit) { - var fraction = output.fraction; - var point = new b2Vec2((1.0 - fraction) * point1.x + fraction * point2.x, (1.0 - fraction) * point1.y + fraction * point2.y); - return callback(fixture, point, output.normal, fraction); - } - return input.maxFraction; - }; - var input = new b2RayCastInput(point1, point2); - broadPhase.RayCast(RayCastWrapper, input); - } - b2World.prototype.RayCastOne = function (point1, point2) { - var __this = this; - var result; - - function RayCastOneWrapper(fixture, point, normal, fraction) { - if (fraction === undefined) fraction = 0; - result = fixture; - return fraction; - }; - __this.RayCast(RayCastOneWrapper, point1, point2); - return result; - } - b2World.prototype.RayCastAll = function (point1, point2) { - var __this = this; - var result = new Vector(); - - function RayCastAllWrapper(fixture, point, normal, fraction) { - if (fraction === undefined) fraction = 0; - result[result.length] = fixture; - return 1; - }; - __this.RayCast(RayCastAllWrapper, point1, point2); - return result; - } - b2World.prototype.GetBodyList = function () { - return this.m_bodyList; - } - b2World.prototype.GetJointList = function () { - return this.m_jointList; - } - b2World.prototype.GetContactList = function () { - return this.m_contactList; - } - b2World.prototype.IsLocked = function () { - return (this.m_flags & b2World.e_locked) > 0; - } - b2World.prototype.Solve = function (step) { - var b; - for (var controller = this.m_controllerList; controller; controller = controller.m_next) { - controller.Step(step); - } - var island = this.m_island; - island.Initialize(this.m_bodyCount, this.m_contactCount, this.m_jointCount, null, this.m_contactManager.m_contactListener, this.m_contactSolver); - for (b = this.m_bodyList; - b; b = b.m_next) { - b.m_flags &= ~b2Body.e_islandFlag; - } - for (var c = this.m_contactList; c; c = c.m_next) { - c.m_flags &= ~b2Contact.e_islandFlag; - } - for (var j = this.m_jointList; j; j = j.m_next) { - j.m_islandFlag = false; - } - var stackSize = parseInt(this.m_bodyCount); - var stack = this.s_stack; - for (var seed = this.m_bodyList; seed; seed = seed.m_next) { - if (seed.m_flags & b2Body.e_islandFlag) { - continue; - } - if (seed.IsAwake() == false || seed.IsActive() == false) { - continue; - } - if (seed.GetType() == b2Body.b2_staticBody) { - continue; - } - island.Clear(); - var stackCount = 0; - stack[stackCount++] = seed; - seed.m_flags |= b2Body.e_islandFlag; - while (stackCount > 0) { - b = stack[--stackCount]; - island.AddBody(b); - if (b.IsAwake() == false) { - b.SetAwake(true); - } - if (b.GetType() == b2Body.b2_staticBody) { - continue; - } - var other; - for (var ce = b.m_contactList; ce; ce = ce.next) { - if (ce.contact.m_flags & b2Contact.e_islandFlag) { - continue; - } - if (ce.contact.IsSensor() == true || ce.contact.IsEnabled() == false || ce.contact.IsTouching() == false) { - continue; - } - island.AddContact(ce.contact); - ce.contact.m_flags |= b2Contact.e_islandFlag; - other = ce.other; - if (other.m_flags & b2Body.e_islandFlag) { - continue; - } - stack[stackCount++] = other; - other.m_flags |= b2Body.e_islandFlag; - } - for (var jn = b.m_jointList; jn; jn = jn.next) { - if (jn.joint.m_islandFlag == true) { - continue; - } - other = jn.other; - if (other.IsActive() == false) { - continue; - } - island.AddJoint(jn.joint); - jn.joint.m_islandFlag = true; - if (other.m_flags & b2Body.e_islandFlag) { - continue; - } - stack[stackCount++] = other; - other.m_flags |= b2Body.e_islandFlag; - } - } - island.Solve(step, this.m_gravity, this.m_allowSleep); - for (var i = 0; i < island.m_bodyCount; ++i) { - b = island.m_bodies[i]; - if (b.GetType() == b2Body.b2_staticBody) { - b.m_flags &= ~b2Body.e_islandFlag; - } - } - } - for (i = 0; - i < stack.length; ++i) { - if (!stack[i]) break; - stack[i] = null; - } - for (b = this.m_bodyList; - b; b = b.m_next) { - if (b.IsAwake() == false || b.IsActive() == false) { - continue; - } - if (b.GetType() == b2Body.b2_staticBody) { - continue; - } - b.SynchronizeFixtures(); - } - this.m_contactManager.FindNewContacts(); - } - b2World.prototype.SolveTOI = function (step) { - var b; - var fA; - var fB; - var bA; - var bB; - var cEdge; - var j; - var island = this.m_island; - island.Initialize(this.m_bodyCount, b2Settings.b2_maxTOIContactsPerIsland, b2Settings.b2_maxTOIJointsPerIsland, null, this.m_contactManager.m_contactListener, this.m_contactSolver); - var queue = b2World.s_queue; - for (b = this.m_bodyList; - b; b = b.m_next) { - b.m_flags &= ~b2Body.e_islandFlag; - b.m_sweep.t0 = 0.0; - } - var c; - for (c = this.m_contactList; - c; c = c.m_next) { - c.m_flags &= ~ (b2Contact.e_toiFlag | b2Contact.e_islandFlag); - } - for (j = this.m_jointList; - j; j = j.m_next) { - j.m_islandFlag = false; - } - for (;;) { - var minContact = null; - var minTOI = 1.0; - for (c = this.m_contactList; - c; c = c.m_next) { - if (c.IsSensor() == true || c.IsEnabled() == false || c.IsContinuous() == false) { - continue; - } - var toi = 1.0; - if (c.m_flags & b2Contact.e_toiFlag) { - toi = c.m_toi; - } - else { - fA = c.m_fixtureA; - fB = c.m_fixtureB; - bA = fA.m_body; - bB = fB.m_body; - if ((bA.GetType() != b2Body.b2_dynamicBody || bA.IsAwake() == false) && (bB.GetType() != b2Body.b2_dynamicBody || bB.IsAwake() == false)) { - continue; - } - var t0 = bA.m_sweep.t0; - if (bA.m_sweep.t0 < bB.m_sweep.t0) { - t0 = bB.m_sweep.t0; - bA.m_sweep.Advance(t0); - } - else if (bB.m_sweep.t0 < bA.m_sweep.t0) { - t0 = bA.m_sweep.t0; - bB.m_sweep.Advance(t0); - } - toi = c.ComputeTOI(bA.m_sweep, bB.m_sweep); - b2Settings.b2Assert(0.0 <= toi && toi <= 1.0); - if (toi > 0.0 && toi < 1.0) { - toi = (1.0 - toi) * t0 + toi; - if (toi > 1) toi = 1; - } - c.m_toi = toi; - c.m_flags |= b2Contact.e_toiFlag; - } - if (Number.MIN_VALUE < toi && toi < minTOI) { - minContact = c; - minTOI = toi; - } - } - if (minContact == null || 1.0 - 100.0 * Number.MIN_VALUE < minTOI) { - break; - } - fA = minContact.m_fixtureA; - fB = minContact.m_fixtureB; - bA = fA.m_body; - bB = fB.m_body; - b2World.s_backupA.Set(bA.m_sweep); - b2World.s_backupB.Set(bB.m_sweep); - bA.Advance(minTOI); - bB.Advance(minTOI); - minContact.Update(this.m_contactManager.m_contactListener); - minContact.m_flags &= ~b2Contact.e_toiFlag; - if (minContact.IsSensor() == true || minContact.IsEnabled() == false) { - bA.m_sweep.Set(b2World.s_backupA); - bB.m_sweep.Set(b2World.s_backupB); - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - continue; - } - if (minContact.IsTouching() == false) { - continue; - } - var seed = bA; - if (seed.GetType() != b2Body.b2_dynamicBody) { - seed = bB; - } - island.Clear(); - var queueStart = 0; - var queueSize = 0; - queue[queueStart + queueSize++] = seed; - seed.m_flags |= b2Body.e_islandFlag; - while (queueSize > 0) { - b = queue[queueStart++]; - --queueSize; - island.AddBody(b); - if (b.IsAwake() == false) { - b.SetAwake(true); - } - if (b.GetType() != b2Body.b2_dynamicBody) { - continue; - } - for (cEdge = b.m_contactList; - cEdge; cEdge = cEdge.next) { - if (island.m_contactCount == island.m_contactCapacity) { - break; - } - if (cEdge.contact.m_flags & b2Contact.e_islandFlag) { - continue; - } - if (cEdge.contact.IsSensor() == true || cEdge.contact.IsEnabled() == false || cEdge.contact.IsTouching() == false) { - continue; - } - island.AddContact(cEdge.contact); - cEdge.contact.m_flags |= b2Contact.e_islandFlag; - var other = cEdge.other; - if (other.m_flags & b2Body.e_islandFlag) { - continue; - } - if (other.GetType() != b2Body.b2_staticBody) { - other.Advance(minTOI); - other.SetAwake(true); - } - queue[queueStart + queueSize] = other; - ++queueSize; - other.m_flags |= b2Body.e_islandFlag; - } - for (var jEdge = b.m_jointList; jEdge; jEdge = jEdge.next) { - if (island.m_jointCount == island.m_jointCapacity) continue; - if (jEdge.joint.m_islandFlag == true) continue; - other = jEdge.other; - if (other.IsActive() == false) { - continue; - } - island.AddJoint(jEdge.joint); - jEdge.joint.m_islandFlag = true; - if (other.m_flags & b2Body.e_islandFlag) continue; - if (other.GetType() != b2Body.b2_staticBody) { - other.Advance(minTOI); - other.SetAwake(true); - } - queue[queueStart + queueSize] = other; - ++queueSize; - other.m_flags |= b2Body.e_islandFlag; - } - } - var subStep = b2World.s_timestep; - subStep.warmStarting = false; - subStep.dt = (1.0 - minTOI) * step.dt; - subStep.inv_dt = 1.0 / subStep.dt; - subStep.dtRatio = 0.0; - subStep.velocityIterations = step.velocityIterations; - subStep.positionIterations = step.positionIterations; - island.SolveTOI(subStep); - var i = 0; - for (i = 0; - i < island.m_bodyCount; ++i) { - b = island.m_bodies[i]; - b.m_flags &= ~b2Body.e_islandFlag; - if (b.IsAwake() == false) { - continue; - } - if (b.GetType() != b2Body.b2_dynamicBody) { - continue; - } - b.SynchronizeFixtures(); - for (cEdge = b.m_contactList; - cEdge; cEdge = cEdge.next) { - cEdge.contact.m_flags &= ~b2Contact.e_toiFlag; - } - } - for (i = 0; - i < island.m_contactCount; ++i) { - c = island.m_contacts[i]; - c.m_flags &= ~ (b2Contact.e_toiFlag | b2Contact.e_islandFlag); - } - for (i = 0; - i < island.m_jointCount; ++i) { - j = island.m_joints[i]; - j.m_islandFlag = false; - } - this.m_contactManager.FindNewContacts(); - } - } - b2World.prototype.DrawJoint = function (joint) { - var b1 = joint.GetBodyA(); - var b2 = joint.GetBodyB(); - var xf1 = b1.m_xf; - var xf2 = b2.m_xf; - var x1 = xf1.position; - var x2 = xf2.position; - var p1 = joint.GetAnchorA(); - var p2 = joint.GetAnchorB(); - var color = b2World.s_jointColor; - switch (joint.m_type) { - case b2Joint.e_distanceJoint: - this.m_debugDraw.DrawSegment(p1, p2, color); - break; - case b2Joint.e_pulleyJoint: - { - var pulley = ((joint instanceof b2PulleyJoint ? joint : null)); - var s1 = pulley.GetGroundAnchorA(); - var s2 = pulley.GetGroundAnchorB(); - this.m_debugDraw.DrawSegment(s1, p1, color); - this.m_debugDraw.DrawSegment(s2, p2, color); - this.m_debugDraw.DrawSegment(s1, s2, color); - } - break; - case b2Joint.e_mouseJoint: - this.m_debugDraw.DrawSegment(p1, p2, color); - break; - default: - if (b1 != this.m_groundBody) this.m_debugDraw.DrawSegment(x1, p1, color); - this.m_debugDraw.DrawSegment(p1, p2, color); - if (b2 != this.m_groundBody) this.m_debugDraw.DrawSegment(x2, p2, color); - } - } - b2World.prototype.DrawShape = function (shape, xf, color) { - switch (shape.m_type) { - case b2Shape.e_circleShape: - { - var circle = ((shape instanceof b2CircleShape ? shape : null)); - var center = b2Math.MulX(xf, circle.m_p); - var radius = circle.m_radius; - var axis = xf.R.col1; - this.m_debugDraw.DrawSolidCircle(center, radius, axis, color); - } - break; - case b2Shape.e_polygonShape: - { - var i = 0; - var poly = ((shape instanceof b2PolygonShape ? shape : null)); - var vertexCount = parseInt(poly.GetVertexCount()); - var localVertices = poly.GetVertices(); - var vertices = new Vector(vertexCount); - for (i = 0; - i < vertexCount; ++i) { - vertices[i] = b2Math.MulX(xf, localVertices[i]); - } - this.m_debugDraw.DrawSolidPolygon(vertices, vertexCount, color); - } - break; - case b2Shape.e_edgeShape: - { - var edge = (shape instanceof b2EdgeShape ? shape : null); - this.m_debugDraw.DrawSegment(b2Math.MulX(xf, edge.GetVertex1()), b2Math.MulX(xf, edge.GetVertex2()), color); - } - break; - } - } - Box2D.postDefs.push(function () { - Box2D.Dynamics.b2World.s_timestep2 = new b2TimeStep(); - Box2D.Dynamics.b2World.s_xf = new b2Transform(); - Box2D.Dynamics.b2World.s_backupA = new b2Sweep(); - Box2D.Dynamics.b2World.s_backupB = new b2Sweep(); - Box2D.Dynamics.b2World.s_timestep = new b2TimeStep(); - Box2D.Dynamics.b2World.s_queue = new Vector(); - Box2D.Dynamics.b2World.s_jointColor = new b2Color(0.5, 0.8, 0.8); - Box2D.Dynamics.b2World.e_newFixture = 0x0001; - Box2D.Dynamics.b2World.e_locked = 0x0002; - }); -})(); -(function () { - var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape, - b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef, - b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape, - b2MassData = Box2D.Collision.Shapes.b2MassData, - b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape, - b2Shape = Box2D.Collision.Shapes.b2Shape, - b2CircleContact = Box2D.Dynamics.Contacts.b2CircleContact, - b2Contact = Box2D.Dynamics.Contacts.b2Contact, - b2ContactConstraint = Box2D.Dynamics.Contacts.b2ContactConstraint, - b2ContactConstraintPoint = Box2D.Dynamics.Contacts.b2ContactConstraintPoint, - b2ContactEdge = Box2D.Dynamics.Contacts.b2ContactEdge, - b2ContactFactory = Box2D.Dynamics.Contacts.b2ContactFactory, - b2ContactRegister = Box2D.Dynamics.Contacts.b2ContactRegister, - b2ContactResult = Box2D.Dynamics.Contacts.b2ContactResult, - b2ContactSolver = Box2D.Dynamics.Contacts.b2ContactSolver, - b2EdgeAndCircleContact = Box2D.Dynamics.Contacts.b2EdgeAndCircleContact, - b2NullContact = Box2D.Dynamics.Contacts.b2NullContact, - b2PolyAndCircleContact = Box2D.Dynamics.Contacts.b2PolyAndCircleContact, - b2PolyAndEdgeContact = Box2D.Dynamics.Contacts.b2PolyAndEdgeContact, - b2PolygonContact = Box2D.Dynamics.Contacts.b2PolygonContact, - b2PositionSolverManifold = Box2D.Dynamics.Contacts.b2PositionSolverManifold, - b2Body = Box2D.Dynamics.b2Body, - b2BodyDef = Box2D.Dynamics.b2BodyDef, - b2ContactFilter = Box2D.Dynamics.b2ContactFilter, - b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse, - b2ContactListener = Box2D.Dynamics.b2ContactListener, - b2ContactManager = Box2D.Dynamics.b2ContactManager, - b2DebugDraw = Box2D.Dynamics.b2DebugDraw, - b2DestructionListener = Box2D.Dynamics.b2DestructionListener, - b2FilterData = Box2D.Dynamics.b2FilterData, - b2Fixture = Box2D.Dynamics.b2Fixture, - b2FixtureDef = Box2D.Dynamics.b2FixtureDef, - b2Island = Box2D.Dynamics.b2Island, - b2TimeStep = Box2D.Dynamics.b2TimeStep, - b2World = Box2D.Dynamics.b2World, - b2Color = Box2D.Common.b2Color, - b2internal = Box2D.Common.b2internal, - b2Settings = Box2D.Common.b2Settings, - b2Mat22 = Box2D.Common.Math.b2Mat22, - b2Mat33 = Box2D.Common.Math.b2Mat33, - b2Math = Box2D.Common.Math.b2Math, - b2Sweep = Box2D.Common.Math.b2Sweep, - b2Transform = Box2D.Common.Math.b2Transform, - b2Vec2 = Box2D.Common.Math.b2Vec2, - b2Vec3 = Box2D.Common.Math.b2Vec3, - b2AABB = Box2D.Collision.b2AABB, - b2Bound = Box2D.Collision.b2Bound, - b2BoundValues = Box2D.Collision.b2BoundValues, - b2Collision = Box2D.Collision.b2Collision, - b2ContactID = Box2D.Collision.b2ContactID, - b2ContactPoint = Box2D.Collision.b2ContactPoint, - b2Distance = Box2D.Collision.b2Distance, - b2DistanceInput = Box2D.Collision.b2DistanceInput, - b2DistanceOutput = Box2D.Collision.b2DistanceOutput, - b2DistanceProxy = Box2D.Collision.b2DistanceProxy, - b2DynamicTree = Box2D.Collision.b2DynamicTree, - b2DynamicTreeBroadPhase = Box2D.Collision.b2DynamicTreeBroadPhase, - b2DynamicTreeNode = Box2D.Collision.b2DynamicTreeNode, - b2DynamicTreePair = Box2D.Collision.b2DynamicTreePair, - b2Manifold = Box2D.Collision.b2Manifold, - b2ManifoldPoint = Box2D.Collision.b2ManifoldPoint, - b2Point = Box2D.Collision.b2Point, - b2RayCastInput = Box2D.Collision.b2RayCastInput, - b2RayCastOutput = Box2D.Collision.b2RayCastOutput, - b2Segment = Box2D.Collision.b2Segment, - b2SeparationFunction = Box2D.Collision.b2SeparationFunction, - b2Simplex = Box2D.Collision.b2Simplex, - b2SimplexCache = Box2D.Collision.b2SimplexCache, - b2SimplexVertex = Box2D.Collision.b2SimplexVertex, - b2TimeOfImpact = Box2D.Collision.b2TimeOfImpact, - b2TOIInput = Box2D.Collision.b2TOIInput, - b2WorldManifold = Box2D.Collision.b2WorldManifold, - ClipVertex = Box2D.Collision.ClipVertex, - Features = Box2D.Collision.Features, - IBroadPhase = Box2D.Collision.IBroadPhase; - - Box2D.inherit(b2CircleContact, Box2D.Dynamics.Contacts.b2Contact); - b2CircleContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype; - b2CircleContact.b2CircleContact = function () { - Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments); - }; - b2CircleContact.Create = function (allocator) { - return new b2CircleContact(); - } - b2CircleContact.Destroy = function (contact, allocator) {} - b2CircleContact.prototype.Reset = function (fixtureA, fixtureB) { - this.__super.Reset.call(this, fixtureA, fixtureB); - } - b2CircleContact.prototype.Evaluate = function () { - var bA = this.m_fixtureA.GetBody(); - var bB = this.m_fixtureB.GetBody(); - b2Collision.CollideCircles(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2CircleShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2CircleShape ? this.m_fixtureB.GetShape() : null), bB.m_xf); - } - b2Contact.b2Contact = function () { - this.m_nodeA = new b2ContactEdge(); - this.m_nodeB = new b2ContactEdge(); - this.m_manifold = new b2Manifold(); - this.m_oldManifold = new b2Manifold(); - }; - b2Contact.prototype.GetManifold = function () { - return this.m_manifold; - } - b2Contact.prototype.GetWorldManifold = function (worldManifold) { - var bodyA = this.m_fixtureA.GetBody(); - var bodyB = this.m_fixtureB.GetBody(); - var shapeA = this.m_fixtureA.GetShape(); - var shapeB = this.m_fixtureB.GetShape(); - worldManifold.Initialize(this.m_manifold, bodyA.GetTransform(), shapeA.m_radius, bodyB.GetTransform(), shapeB.m_radius); - } - b2Contact.prototype.IsTouching = function () { - return (this.m_flags & b2Contact.e_touchingFlag) == b2Contact.e_touchingFlag; - } - b2Contact.prototype.IsContinuous = function () { - return (this.m_flags & b2Contact.e_continuousFlag) == b2Contact.e_continuousFlag; - } - b2Contact.prototype.SetSensor = function (sensor) { - if (sensor) { - this.m_flags |= b2Contact.e_sensorFlag; - } - else { - this.m_flags &= ~b2Contact.e_sensorFlag; - } - } - b2Contact.prototype.IsSensor = function () { - return (this.m_flags & b2Contact.e_sensorFlag) == b2Contact.e_sensorFlag; - } - b2Contact.prototype.SetEnabled = function (flag) { - if (flag) { - this.m_flags |= b2Contact.e_enabledFlag; - } - else { - this.m_flags &= ~b2Contact.e_enabledFlag; - } - } - b2Contact.prototype.IsEnabled = function () { - return (this.m_flags & b2Contact.e_enabledFlag) == b2Contact.e_enabledFlag; - } - b2Contact.prototype.GetNext = function () { - return this.m_next; - } - b2Contact.prototype.GetFixtureA = function () { - return this.m_fixtureA; - } - b2Contact.prototype.GetFixtureB = function () { - return this.m_fixtureB; - } - b2Contact.prototype.FlagForFiltering = function () { - this.m_flags |= b2Contact.e_filterFlag; - } - b2Contact.prototype.b2Contact = function () {} - b2Contact.prototype.Reset = function (fixtureA, fixtureB) { - if (fixtureA === undefined) fixtureA = null; - if (fixtureB === undefined) fixtureB = null; - this.m_flags = b2Contact.e_enabledFlag; - if (!fixtureA || !fixtureB) { - this.m_fixtureA = null; - this.m_fixtureB = null; - return; - } - if (fixtureA.IsSensor() || fixtureB.IsSensor()) { - this.m_flags |= b2Contact.e_sensorFlag; - } - var bodyA = fixtureA.GetBody(); - var bodyB = fixtureB.GetBody(); - if (bodyA.GetType() != b2Body.b2_dynamicBody || bodyA.IsBullet() || bodyB.GetType() != b2Body.b2_dynamicBody || bodyB.IsBullet()) { - this.m_flags |= b2Contact.e_continuousFlag; - } - this.m_fixtureA = fixtureA; - this.m_fixtureB = fixtureB; - this.m_manifold.m_pointCount = 0; - this.m_prev = null; - this.m_next = null; - this.m_nodeA.contact = null; - this.m_nodeA.prev = null; - this.m_nodeA.next = null; - this.m_nodeA.other = null; - this.m_nodeB.contact = null; - this.m_nodeB.prev = null; - this.m_nodeB.next = null; - this.m_nodeB.other = null; - } - b2Contact.prototype.Update = function (listener) { - var tManifold = this.m_oldManifold; - this.m_oldManifold = this.m_manifold; - this.m_manifold = tManifold; - this.m_flags |= b2Contact.e_enabledFlag; - var touching = false; - var wasTouching = (this.m_flags & b2Contact.e_touchingFlag) == b2Contact.e_touchingFlag; - var bodyA = this.m_fixtureA.m_body; - var bodyB = this.m_fixtureB.m_body; - var aabbOverlap = this.m_fixtureA.m_aabb.TestOverlap(this.m_fixtureB.m_aabb); - if (this.m_flags & b2Contact.e_sensorFlag) { - if (aabbOverlap) { - var shapeA = this.m_fixtureA.GetShape(); - var shapeB = this.m_fixtureB.GetShape(); - var xfA = bodyA.GetTransform(); - var xfB = bodyB.GetTransform(); - touching = b2Shape.TestOverlap(shapeA, xfA, shapeB, xfB); - } - this.m_manifold.m_pointCount = 0; - } - else { - if (bodyA.GetType() != b2Body.b2_dynamicBody || bodyA.IsBullet() || bodyB.GetType() != b2Body.b2_dynamicBody || bodyB.IsBullet()) { - this.m_flags |= b2Contact.e_continuousFlag; - } - else { - this.m_flags &= ~b2Contact.e_continuousFlag; - } - if (aabbOverlap) { - this.Evaluate(); - touching = this.m_manifold.m_pointCount > 0; - for (var i = 0; i < this.m_manifold.m_pointCount; ++i) { - var mp2 = this.m_manifold.m_points[i]; - mp2.m_normalImpulse = 0.0; - mp2.m_tangentImpulse = 0.0; - var id2 = mp2.m_id; - for (var j = 0; j < this.m_oldManifold.m_pointCount; ++j) { - var mp1 = this.m_oldManifold.m_points[j]; - if (mp1.m_id.key == id2.key) { - mp2.m_normalImpulse = mp1.m_normalImpulse; - mp2.m_tangentImpulse = mp1.m_tangentImpulse; - break; - } - } - } - } - else { - this.m_manifold.m_pointCount = 0; - } - if (touching != wasTouching) { - bodyA.SetAwake(true); - bodyB.SetAwake(true); - } - } - if (touching) { - this.m_flags |= b2Contact.e_touchingFlag; - } - else { - this.m_flags &= ~b2Contact.e_touchingFlag; - } - if (wasTouching == false && touching == true) { - listener.BeginContact(this); - } - if (wasTouching == true && touching == false) { - listener.EndContact(this); - } - if ((this.m_flags & b2Contact.e_sensorFlag) == 0) { - listener.PreSolve(this, this.m_oldManifold); - } - } - b2Contact.prototype.Evaluate = function () {} - b2Contact.prototype.ComputeTOI = function (sweepA, sweepB) { - b2Contact.s_input.proxyA.Set(this.m_fixtureA.GetShape()); - b2Contact.s_input.proxyB.Set(this.m_fixtureB.GetShape()); - b2Contact.s_input.sweepA = sweepA; - b2Contact.s_input.sweepB = sweepB; - b2Contact.s_input.tolerance = b2Settings.b2_linearSlop; - return b2TimeOfImpact.TimeOfImpact(b2Contact.s_input); - } - Box2D.postDefs.push(function () { - Box2D.Dynamics.Contacts.b2Contact.e_sensorFlag = 0x0001; - Box2D.Dynamics.Contacts.b2Contact.e_continuousFlag = 0x0002; - Box2D.Dynamics.Contacts.b2Contact.e_islandFlag = 0x0004; - Box2D.Dynamics.Contacts.b2Contact.e_toiFlag = 0x0008; - Box2D.Dynamics.Contacts.b2Contact.e_touchingFlag = 0x0010; - Box2D.Dynamics.Contacts.b2Contact.e_enabledFlag = 0x0020; - Box2D.Dynamics.Contacts.b2Contact.e_filterFlag = 0x0040; - Box2D.Dynamics.Contacts.b2Contact.s_input = new b2TOIInput(); - }); - b2ContactConstraint.b2ContactConstraint = function () { - this.localPlaneNormal = new b2Vec2(); - this.localPoint = new b2Vec2(); - this.normal = new b2Vec2(); - this.normalMass = new b2Mat22(); - this.K = new b2Mat22(); - }; - b2ContactConstraint.prototype.b2ContactConstraint = function () { - this.points = new Vector(b2Settings.b2_maxManifoldPoints); - for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { - this.points[i] = new b2ContactConstraintPoint(); - } - } - b2ContactConstraintPoint.b2ContactConstraintPoint = function () { - this.localPoint = new b2Vec2(); - this.rA = new b2Vec2(); - this.rB = new b2Vec2(); - }; - b2ContactEdge.b2ContactEdge = function () {}; - b2ContactFactory.b2ContactFactory = function () {}; - b2ContactFactory.prototype.b2ContactFactory = function (allocator) { - this.m_allocator = allocator; - this.InitializeRegisters(); - } - b2ContactFactory.prototype.AddType = function (createFcn, destroyFcn, type1, type2) { - if (type1 === undefined) type1 = 0; - if (type2 === undefined) type2 = 0; - this.m_registers[type1][type2].createFcn = createFcn; - this.m_registers[type1][type2].destroyFcn = destroyFcn; - this.m_registers[type1][type2].primary = true; - if (type1 != type2) { - this.m_registers[type2][type1].createFcn = createFcn; - this.m_registers[type2][type1].destroyFcn = destroyFcn; - this.m_registers[type2][type1].primary = false; - } - } - b2ContactFactory.prototype.InitializeRegisters = function () { - this.m_registers = new Vector(b2Shape.e_shapeTypeCount); - for (var i = 0; i < b2Shape.e_shapeTypeCount; i++) { - this.m_registers[i] = new Vector(b2Shape.e_shapeTypeCount); - for (var j = 0; j < b2Shape.e_shapeTypeCount; j++) { - this.m_registers[i][j] = new b2ContactRegister(); - } - } - this.AddType(b2CircleContact.Create, b2CircleContact.Destroy, b2Shape.e_circleShape, b2Shape.e_circleShape); - this.AddType(b2PolyAndCircleContact.Create, b2PolyAndCircleContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_circleShape); - this.AddType(b2PolygonContact.Create, b2PolygonContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_polygonShape); - this.AddType(b2EdgeAndCircleContact.Create, b2EdgeAndCircleContact.Destroy, b2Shape.e_edgeShape, b2Shape.e_circleShape); - this.AddType(b2PolyAndEdgeContact.Create, b2PolyAndEdgeContact.Destroy, b2Shape.e_polygonShape, b2Shape.e_edgeShape); - } - b2ContactFactory.prototype.Create = function (fixtureA, fixtureB) { - var type1 = parseInt(fixtureA.GetType()); - var type2 = parseInt(fixtureB.GetType()); - var reg = this.m_registers[type1][type2]; - var c; - if (reg.pool) { - c = reg.pool; - reg.pool = c.m_next; - reg.poolCount--; - c.Reset(fixtureA, fixtureB); - return c; - } - var createFcn = reg.createFcn; - if (createFcn != null) { - if (reg.primary) { - c = createFcn(this.m_allocator); - c.Reset(fixtureA, fixtureB); - return c; - } - else { - c = createFcn(this.m_allocator); - c.Reset(fixtureB, fixtureA); - return c; - } - } - else { - return null; - } - } - b2ContactFactory.prototype.Destroy = function (contact) { - if (contact.m_manifold.m_pointCount > 0) { - contact.m_fixtureA.m_body.SetAwake(true); - contact.m_fixtureB.m_body.SetAwake(true); - } - var type1 = parseInt(contact.m_fixtureA.GetType()); - var type2 = parseInt(contact.m_fixtureB.GetType()); - var reg = this.m_registers[type1][type2]; - if (true) { - reg.poolCount++; - contact.m_next = reg.pool; - reg.pool = contact; - } - var destroyFcn = reg.destroyFcn; - destroyFcn(contact, this.m_allocator); - } - b2ContactRegister.b2ContactRegister = function () {}; - b2ContactResult.b2ContactResult = function () { - this.position = new b2Vec2(); - this.normal = new b2Vec2(); - this.id = new b2ContactID(); - }; - b2ContactSolver.b2ContactSolver = function () { - this.m_step = new b2TimeStep(); - this.m_constraints = new Vector(); - }; - b2ContactSolver.prototype.b2ContactSolver = function () {} - b2ContactSolver.prototype.Initialize = function (step, contacts, contactCount, allocator) { - if (contactCount === undefined) contactCount = 0; - var contact; - this.m_step.Set(step); - this.m_allocator = allocator; - var i = 0; - var tVec; - var tMat; - this.m_constraintCount = contactCount; - while (this.m_constraints.length < this.m_constraintCount) { - this.m_constraints[this.m_constraints.length] = new b2ContactConstraint(); - } - for (i = 0; - i < contactCount; ++i) { - contact = contacts[i]; - var fixtureA = contact.m_fixtureA; - var fixtureB = contact.m_fixtureB; - var shapeA = fixtureA.m_shape; - var shapeB = fixtureB.m_shape; - var radiusA = shapeA.m_radius; - var radiusB = shapeB.m_radius; - var bodyA = fixtureA.m_body; - var bodyB = fixtureB.m_body; - var manifold = contact.GetManifold(); - var friction = b2Settings.b2MixFriction(fixtureA.GetFriction(), fixtureB.GetFriction()); - var restitution = b2Settings.b2MixRestitution(fixtureA.GetRestitution(), fixtureB.GetRestitution()); - var vAX = bodyA.m_linearVelocity.x; - var vAY = bodyA.m_linearVelocity.y; - var vBX = bodyB.m_linearVelocity.x; - var vBY = bodyB.m_linearVelocity.y; - var wA = bodyA.m_angularVelocity; - var wB = bodyB.m_angularVelocity; - b2Settings.b2Assert(manifold.m_pointCount > 0); - b2ContactSolver.s_worldManifold.Initialize(manifold, bodyA.m_xf, radiusA, bodyB.m_xf, radiusB); - var normalX = b2ContactSolver.s_worldManifold.m_normal.x; - var normalY = b2ContactSolver.s_worldManifold.m_normal.y; - var cc = this.m_constraints[i]; - cc.bodyA = bodyA; - cc.bodyB = bodyB; - cc.manifold = manifold; - cc.normal.x = normalX; - cc.normal.y = normalY; - cc.pointCount = manifold.m_pointCount; - cc.friction = friction; - cc.restitution = restitution; - cc.localPlaneNormal.x = manifold.m_localPlaneNormal.x; - cc.localPlaneNormal.y = manifold.m_localPlaneNormal.y; - cc.localPoint.x = manifold.m_localPoint.x; - cc.localPoint.y = manifold.m_localPoint.y; - cc.radius = radiusA + radiusB; - cc.type = manifold.m_type; - for (var k = 0; k < cc.pointCount; ++k) { - var cp = manifold.m_points[k]; - var ccp = cc.points[k]; - ccp.normalImpulse = cp.m_normalImpulse; - ccp.tangentImpulse = cp.m_tangentImpulse; - ccp.localPoint.SetV(cp.m_localPoint); - var rAX = ccp.rA.x = b2ContactSolver.s_worldManifold.m_points[k].x - bodyA.m_sweep.c.x; - var rAY = ccp.rA.y = b2ContactSolver.s_worldManifold.m_points[k].y - bodyA.m_sweep.c.y; - var rBX = ccp.rB.x = b2ContactSolver.s_worldManifold.m_points[k].x - bodyB.m_sweep.c.x; - var rBY = ccp.rB.y = b2ContactSolver.s_worldManifold.m_points[k].y - bodyB.m_sweep.c.y; - var rnA = rAX * normalY - rAY * normalX; - var rnB = rBX * normalY - rBY * normalX; - rnA *= rnA; - rnB *= rnB; - var kNormal = bodyA.m_invMass + bodyB.m_invMass + bodyA.m_invI * rnA + bodyB.m_invI * rnB; - ccp.normalMass = 1.0 / kNormal; - var kEqualized = bodyA.m_mass * bodyA.m_invMass + bodyB.m_mass * bodyB.m_invMass; - kEqualized += bodyA.m_mass * bodyA.m_invI * rnA + bodyB.m_mass * bodyB.m_invI * rnB; - ccp.equalizedMass = 1.0 / kEqualized; - var tangentX = normalY; - var tangentY = (-normalX); - var rtA = rAX * tangentY - rAY * tangentX; - var rtB = rBX * tangentY - rBY * tangentX; - rtA *= rtA; - rtB *= rtB; - var kTangent = bodyA.m_invMass + bodyB.m_invMass + bodyA.m_invI * rtA + bodyB.m_invI * rtB; - ccp.tangentMass = 1.0 / kTangent; - ccp.velocityBias = 0.0; - var tX = vBX + ((-wB * rBY)) - vAX - ((-wA * rAY)); - var tY = vBY + (wB * rBX) - vAY - (wA * rAX); - var vRel = cc.normal.x * tX + cc.normal.y * tY; - if (vRel < (-b2Settings.b2_velocityThreshold)) { - ccp.velocityBias += (-cc.restitution * vRel); - } - } - if (cc.pointCount == 2) { - var ccp1 = cc.points[0]; - var ccp2 = cc.points[1]; - var invMassA = bodyA.m_invMass; - var invIA = bodyA.m_invI; - var invMassB = bodyB.m_invMass; - var invIB = bodyB.m_invI; - var rn1A = ccp1.rA.x * normalY - ccp1.rA.y * normalX; - var rn1B = ccp1.rB.x * normalY - ccp1.rB.y * normalX; - var rn2A = ccp2.rA.x * normalY - ccp2.rA.y * normalX; - var rn2B = ccp2.rB.x * normalY - ccp2.rB.y * normalX; - var k11 = invMassA + invMassB + invIA * rn1A * rn1A + invIB * rn1B * rn1B; - var k22 = invMassA + invMassB + invIA * rn2A * rn2A + invIB * rn2B * rn2B; - var k12 = invMassA + invMassB + invIA * rn1A * rn2A + invIB * rn1B * rn2B; - var k_maxConditionNumber = 100.0; - if (k11 * k11 < k_maxConditionNumber * (k11 * k22 - k12 * k12)) { - cc.K.col1.Set(k11, k12); - cc.K.col2.Set(k12, k22); - cc.K.GetInverse(cc.normalMass); - } - else { - cc.pointCount = 1; - } - } - } - } - b2ContactSolver.prototype.InitVelocityConstraints = function (step) { - var tVec; - var tVec2; - var tMat; - for (var i = 0; i < this.m_constraintCount; ++i) { - var c = this.m_constraints[i]; - var bodyA = c.bodyA; - var bodyB = c.bodyB; - var invMassA = bodyA.m_invMass; - var invIA = bodyA.m_invI; - var invMassB = bodyB.m_invMass; - var invIB = bodyB.m_invI; - var normalX = c.normal.x; - var normalY = c.normal.y; - var tangentX = normalY; - var tangentY = (-normalX); - var tX = 0; - var j = 0; - var tCount = 0; - if (step.warmStarting) { - tCount = c.pointCount; - for (j = 0; - j < tCount; ++j) { - var ccp = c.points[j]; - ccp.normalImpulse *= step.dtRatio; - ccp.tangentImpulse *= step.dtRatio; - var PX = ccp.normalImpulse * normalX + ccp.tangentImpulse * tangentX; - var PY = ccp.normalImpulse * normalY + ccp.tangentImpulse * tangentY; - bodyA.m_angularVelocity -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX); - bodyA.m_linearVelocity.x -= invMassA * PX; - bodyA.m_linearVelocity.y -= invMassA * PY; - bodyB.m_angularVelocity += invIB * (ccp.rB.x * PY - ccp.rB.y * PX); - bodyB.m_linearVelocity.x += invMassB * PX; - bodyB.m_linearVelocity.y += invMassB * PY; - } - } - else { - tCount = c.pointCount; - for (j = 0; - j < tCount; ++j) { - var ccp2 = c.points[j]; - ccp2.normalImpulse = 0.0; - ccp2.tangentImpulse = 0.0; - } - } - } - } - b2ContactSolver.prototype.SolveVelocityConstraints = function () { - var j = 0; - var ccp; - var rAX = 0; - var rAY = 0; - var rBX = 0; - var rBY = 0; - var dvX = 0; - var dvY = 0; - var vn = 0; - var vt = 0; - var lambda = 0; - var maxFriction = 0; - var newImpulse = 0; - var PX = 0; - var PY = 0; - var dX = 0; - var dY = 0; - var P1X = 0; - var P1Y = 0; - var P2X = 0; - var P2Y = 0; - var tMat; - var tVec; - for (var i = 0; i < this.m_constraintCount; ++i) { - var c = this.m_constraints[i]; - var bodyA = c.bodyA; - var bodyB = c.bodyB; - var wA = bodyA.m_angularVelocity; - var wB = bodyB.m_angularVelocity; - var vA = bodyA.m_linearVelocity; - var vB = bodyB.m_linearVelocity; - var invMassA = bodyA.m_invMass; - var invIA = bodyA.m_invI; - var invMassB = bodyB.m_invMass; - var invIB = bodyB.m_invI; - var normalX = c.normal.x; - var normalY = c.normal.y; - var tangentX = normalY; - var tangentY = (-normalX); - var friction = c.friction; - var tX = 0; - for (j = 0; - j < c.pointCount; j++) { - ccp = c.points[j]; - dvX = vB.x - wB * ccp.rB.y - vA.x + wA * ccp.rA.y; - dvY = vB.y + wB * ccp.rB.x - vA.y - wA * ccp.rA.x; - vt = dvX * tangentX + dvY * tangentY; - lambda = ccp.tangentMass * (-vt); - maxFriction = friction * ccp.normalImpulse; - newImpulse = b2Math.Clamp(ccp.tangentImpulse + lambda, (-maxFriction), maxFriction); - lambda = newImpulse - ccp.tangentImpulse; - PX = lambda * tangentX; - PY = lambda * tangentY; - vA.x -= invMassA * PX; - vA.y -= invMassA * PY; - wA -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX); - vB.x += invMassB * PX; - vB.y += invMassB * PY; - wB += invIB * (ccp.rB.x * PY - ccp.rB.y * PX); - ccp.tangentImpulse = newImpulse; - } - var tCount = parseInt(c.pointCount); - if (c.pointCount == 1) { - ccp = c.points[0]; - dvX = vB.x + ((-wB * ccp.rB.y)) - vA.x - ((-wA * ccp.rA.y)); - dvY = vB.y + (wB * ccp.rB.x) - vA.y - (wA * ccp.rA.x); - vn = dvX * normalX + dvY * normalY; - lambda = (-ccp.normalMass * (vn - ccp.velocityBias)); - newImpulse = ccp.normalImpulse + lambda; - newImpulse = newImpulse > 0 ? newImpulse : 0.0; - lambda = newImpulse - ccp.normalImpulse; - PX = lambda * normalX; - PY = lambda * normalY; - vA.x -= invMassA * PX; - vA.y -= invMassA * PY; - wA -= invIA * (ccp.rA.x * PY - ccp.rA.y * PX); - vB.x += invMassB * PX; - vB.y += invMassB * PY; - wB += invIB * (ccp.rB.x * PY - ccp.rB.y * PX); - ccp.normalImpulse = newImpulse; - } - else { - var cp1 = c.points[0]; - var cp2 = c.points[1]; - var aX = cp1.normalImpulse; - var aY = cp2.normalImpulse; - var dv1X = vB.x - wB * cp1.rB.y - vA.x + wA * cp1.rA.y; - var dv1Y = vB.y + wB * cp1.rB.x - vA.y - wA * cp1.rA.x; - var dv2X = vB.x - wB * cp2.rB.y - vA.x + wA * cp2.rA.y; - var dv2Y = vB.y + wB * cp2.rB.x - vA.y - wA * cp2.rA.x; - var vn1 = dv1X * normalX + dv1Y * normalY; - var vn2 = dv2X * normalX + dv2Y * normalY; - var bX = vn1 - cp1.velocityBias; - var bY = vn2 - cp2.velocityBias; - tMat = c.K; - bX -= tMat.col1.x * aX + tMat.col2.x * aY; - bY -= tMat.col1.y * aX + tMat.col2.y * aY; - var k_errorTol = 0.001; - for (;;) { - tMat = c.normalMass; - var xX = (-(tMat.col1.x * bX + tMat.col2.x * bY)); - var xY = (-(tMat.col1.y * bX + tMat.col2.y * bY)); - if (xX >= 0.0 && xY >= 0.0) { - dX = xX - aX; - dY = xY - aY; - P1X = dX * normalX; - P1Y = dX * normalY; - P2X = dY * normalX; - P2Y = dY * normalY; - vA.x -= invMassA * (P1X + P2X); - vA.y -= invMassA * (P1Y + P2Y); - wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X); - vB.x += invMassB * (P1X + P2X); - vB.y += invMassB * (P1Y + P2Y); - wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X); - cp1.normalImpulse = xX; - cp2.normalImpulse = xY; - break; - } - xX = (-cp1.normalMass * bX); - xY = 0.0; - vn1 = 0.0; - vn2 = c.K.col1.y * xX + bY; - if (xX >= 0.0 && vn2 >= 0.0) { - dX = xX - aX; - dY = xY - aY; - P1X = dX * normalX; - P1Y = dX * normalY; - P2X = dY * normalX; - P2Y = dY * normalY; - vA.x -= invMassA * (P1X + P2X); - vA.y -= invMassA * (P1Y + P2Y); - wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X); - vB.x += invMassB * (P1X + P2X); - vB.y += invMassB * (P1Y + P2Y); - wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X); - cp1.normalImpulse = xX; - cp2.normalImpulse = xY; - break; - } - xX = 0.0; - xY = (-cp2.normalMass * bY); - vn1 = c.K.col2.x * xY + bX; - vn2 = 0.0; - if (xY >= 0.0 && vn1 >= 0.0) { - dX = xX - aX; - dY = xY - aY; - P1X = dX * normalX; - P1Y = dX * normalY; - P2X = dY * normalX; - P2Y = dY * normalY; - vA.x -= invMassA * (P1X + P2X); - vA.y -= invMassA * (P1Y + P2Y); - wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X); - vB.x += invMassB * (P1X + P2X); - vB.y += invMassB * (P1Y + P2Y); - wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X); - cp1.normalImpulse = xX; - cp2.normalImpulse = xY; - break; - } - xX = 0.0; - xY = 0.0; - vn1 = bX; - vn2 = bY; - if (vn1 >= 0.0 && vn2 >= 0.0) { - dX = xX - aX; - dY = xY - aY; - P1X = dX * normalX; - P1Y = dX * normalY; - P2X = dY * normalX; - P2Y = dY * normalY; - vA.x -= invMassA * (P1X + P2X); - vA.y -= invMassA * (P1Y + P2Y); - wA -= invIA * (cp1.rA.x * P1Y - cp1.rA.y * P1X + cp2.rA.x * P2Y - cp2.rA.y * P2X); - vB.x += invMassB * (P1X + P2X); - vB.y += invMassB * (P1Y + P2Y); - wB += invIB * (cp1.rB.x * P1Y - cp1.rB.y * P1X + cp2.rB.x * P2Y - cp2.rB.y * P2X); - cp1.normalImpulse = xX; - cp2.normalImpulse = xY; - break; - } - break; - } - } - bodyA.m_angularVelocity = wA; - bodyB.m_angularVelocity = wB; - } - } - b2ContactSolver.prototype.FinalizeVelocityConstraints = function () { - for (var i = 0; i < this.m_constraintCount; ++i) { - var c = this.m_constraints[i]; - var m = c.manifold; - for (var j = 0; j < c.pointCount; ++j) { - var point1 = m.m_points[j]; - var point2 = c.points[j]; - point1.m_normalImpulse = point2.normalImpulse; - point1.m_tangentImpulse = point2.tangentImpulse; - } - } - } - b2ContactSolver.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - var minSeparation = 0.0; - for (var i = 0; i < this.m_constraintCount; i++) { - var c = this.m_constraints[i]; - var bodyA = c.bodyA; - var bodyB = c.bodyB; - var invMassA = bodyA.m_mass * bodyA.m_invMass; - var invIA = bodyA.m_mass * bodyA.m_invI; - var invMassB = bodyB.m_mass * bodyB.m_invMass; - var invIB = bodyB.m_mass * bodyB.m_invI; - b2ContactSolver.s_psm.Initialize(c); - var normal = b2ContactSolver.s_psm.m_normal; - for (var j = 0; j < c.pointCount; j++) { - var ccp = c.points[j]; - var point = b2ContactSolver.s_psm.m_points[j]; - var separation = b2ContactSolver.s_psm.m_separations[j]; - var rAX = point.x - bodyA.m_sweep.c.x; - var rAY = point.y - bodyA.m_sweep.c.y; - var rBX = point.x - bodyB.m_sweep.c.x; - var rBY = point.y - bodyB.m_sweep.c.y; - minSeparation = minSeparation < separation ? minSeparation : separation; - var C = b2Math.Clamp(baumgarte * (separation + b2Settings.b2_linearSlop), (-b2Settings.b2_maxLinearCorrection), 0.0); - var impulse = (-ccp.equalizedMass * C); - var PX = impulse * normal.x; - var PY = impulse * normal.y;bodyA.m_sweep.c.x -= invMassA * PX; - bodyA.m_sweep.c.y -= invMassA * PY; - bodyA.m_sweep.a -= invIA * (rAX * PY - rAY * PX); - bodyA.SynchronizeTransform(); - bodyB.m_sweep.c.x += invMassB * PX; - bodyB.m_sweep.c.y += invMassB * PY; - bodyB.m_sweep.a += invIB * (rBX * PY - rBY * PX); - bodyB.SynchronizeTransform(); - } - } - return minSeparation > (-1.5 * b2Settings.b2_linearSlop); - } - Box2D.postDefs.push(function () { - Box2D.Dynamics.Contacts.b2ContactSolver.s_worldManifold = new b2WorldManifold(); - Box2D.Dynamics.Contacts.b2ContactSolver.s_psm = new b2PositionSolverManifold(); - }); - Box2D.inherit(b2EdgeAndCircleContact, Box2D.Dynamics.Contacts.b2Contact); - b2EdgeAndCircleContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype; - b2EdgeAndCircleContact.b2EdgeAndCircleContact = function () { - Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments); - }; - b2EdgeAndCircleContact.Create = function (allocator) { - return new b2EdgeAndCircleContact(); - } - b2EdgeAndCircleContact.Destroy = function (contact, allocator) {} - b2EdgeAndCircleContact.prototype.Reset = function (fixtureA, fixtureB) { - this.__super.Reset.call(this, fixtureA, fixtureB); - } - b2EdgeAndCircleContact.prototype.Evaluate = function () { - var bA = this.m_fixtureA.GetBody(); - var bB = this.m_fixtureB.GetBody(); - this.b2CollideEdgeAndCircle(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2EdgeShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2CircleShape ? this.m_fixtureB.GetShape() : null), bB.m_xf); - } - b2EdgeAndCircleContact.prototype.b2CollideEdgeAndCircle = function (manifold, edge, xf1, circle, xf2) {} - Box2D.inherit(b2NullContact, Box2D.Dynamics.Contacts.b2Contact); - b2NullContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype; - b2NullContact.b2NullContact = function () { - Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments); - }; - b2NullContact.prototype.b2NullContact = function () { - this.__super.b2Contact.call(this); - } - b2NullContact.prototype.Evaluate = function () {} - Box2D.inherit(b2PolyAndCircleContact, Box2D.Dynamics.Contacts.b2Contact); - b2PolyAndCircleContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype; - b2PolyAndCircleContact.b2PolyAndCircleContact = function () { - Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments); - }; - b2PolyAndCircleContact.Create = function (allocator) { - return new b2PolyAndCircleContact(); - } - b2PolyAndCircleContact.Destroy = function (contact, allocator) {} - b2PolyAndCircleContact.prototype.Reset = function (fixtureA, fixtureB) { - this.__super.Reset.call(this, fixtureA, fixtureB); - b2Settings.b2Assert(fixtureA.GetType() == b2Shape.e_polygonShape); - b2Settings.b2Assert(fixtureB.GetType() == b2Shape.e_circleShape); - } - b2PolyAndCircleContact.prototype.Evaluate = function () { - var bA = this.m_fixtureA.m_body; - var bB = this.m_fixtureB.m_body; - b2Collision.CollidePolygonAndCircle(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2PolygonShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2CircleShape ? this.m_fixtureB.GetShape() : null), bB.m_xf); - } - Box2D.inherit(b2PolyAndEdgeContact, Box2D.Dynamics.Contacts.b2Contact); - b2PolyAndEdgeContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype; - b2PolyAndEdgeContact.b2PolyAndEdgeContact = function () { - Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments); - }; - b2PolyAndEdgeContact.Create = function (allocator) { - return new b2PolyAndEdgeContact(); - } - b2PolyAndEdgeContact.Destroy = function (contact, allocator) {} - b2PolyAndEdgeContact.prototype.Reset = function (fixtureA, fixtureB) { - this.__super.Reset.call(this, fixtureA, fixtureB); - b2Settings.b2Assert(fixtureA.GetType() == b2Shape.e_polygonShape); - b2Settings.b2Assert(fixtureB.GetType() == b2Shape.e_edgeShape); - } - b2PolyAndEdgeContact.prototype.Evaluate = function () { - var bA = this.m_fixtureA.GetBody(); - var bB = this.m_fixtureB.GetBody(); - this.b2CollidePolyAndEdge(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2PolygonShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2EdgeShape ? this.m_fixtureB.GetShape() : null), bB.m_xf); - } - b2PolyAndEdgeContact.prototype.b2CollidePolyAndEdge = function (manifold, polygon, xf1, edge, xf2) {} - Box2D.inherit(b2PolygonContact, Box2D.Dynamics.Contacts.b2Contact); - b2PolygonContact.prototype.__super = Box2D.Dynamics.Contacts.b2Contact.prototype; - b2PolygonContact.b2PolygonContact = function () { - Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this, arguments); - }; - b2PolygonContact.Create = function (allocator) { - return new b2PolygonContact(); - } - b2PolygonContact.Destroy = function (contact, allocator) {} - b2PolygonContact.prototype.Reset = function (fixtureA, fixtureB) { - this.__super.Reset.call(this, fixtureA, fixtureB); - } - b2PolygonContact.prototype.Evaluate = function () { - var bA = this.m_fixtureA.GetBody(); - var bB = this.m_fixtureB.GetBody(); - b2Collision.CollidePolygons(this.m_manifold, (this.m_fixtureA.GetShape() instanceof b2PolygonShape ? this.m_fixtureA.GetShape() : null), bA.m_xf, (this.m_fixtureB.GetShape() instanceof b2PolygonShape ? this.m_fixtureB.GetShape() : null), bB.m_xf); - } - b2PositionSolverManifold.b2PositionSolverManifold = function () {}; - b2PositionSolverManifold.prototype.b2PositionSolverManifold = function () { - this.m_normal = new b2Vec2(); - this.m_separations = new Vector_a2j_Number(b2Settings.b2_maxManifoldPoints); - this.m_points = new Vector(b2Settings.b2_maxManifoldPoints); - for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++) { - this.m_points[i] = new b2Vec2(); - } - } - b2PositionSolverManifold.prototype.Initialize = function (cc) { - b2Settings.b2Assert(cc.pointCount > 0); - var i = 0; - var clipPointX = 0; - var clipPointY = 0; - var tMat; - var tVec; - var planePointX = 0; - var planePointY = 0; - switch (cc.type) { - case b2Manifold.e_circles: - { - tMat = cc.bodyA.m_xf.R; - tVec = cc.localPoint; - var pointAX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var pointAY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tMat = cc.bodyB.m_xf.R; - tVec = cc.points[0].localPoint; - var pointBX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - var pointBY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - var dX = pointBX - pointAX; - var dY = pointBY - pointAY; - var d2 = dX * dX + dY * dY; - if (d2 > Number.MIN_VALUE * Number.MIN_VALUE) { - var d = Math.sqrt(d2); - this.m_normal.x = dX / d; - this.m_normal.y = dY / d; - } - else { - this.m_normal.x = 1.0; - this.m_normal.y = 0.0; - } - this.m_points[0].x = 0.5 * (pointAX + pointBX); - this.m_points[0].y = 0.5 * (pointAY + pointBY); - this.m_separations[0] = dX * this.m_normal.x + dY * this.m_normal.y - cc.radius; - } - break; - case b2Manifold.e_faceA: - { - tMat = cc.bodyA.m_xf.R; - tVec = cc.localPlaneNormal; - this.m_normal.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - this.m_normal.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = cc.bodyA.m_xf.R; - tVec = cc.localPoint; - planePointX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - planePointY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tMat = cc.bodyB.m_xf.R; - for (i = 0; - i < cc.pointCount; ++i) { - tVec = cc.points[i].localPoint; - clipPointX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - clipPointY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - this.m_separations[i] = (clipPointX - planePointX) * this.m_normal.x + (clipPointY - planePointY) * this.m_normal.y - cc.radius; - this.m_points[i].x = clipPointX; - this.m_points[i].y = clipPointY; - } - } - break; - case b2Manifold.e_faceB: - { - tMat = cc.bodyB.m_xf.R; - tVec = cc.localPlaneNormal; - this.m_normal.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - this.m_normal.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = cc.bodyB.m_xf.R; - tVec = cc.localPoint; - planePointX = cc.bodyB.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - planePointY = cc.bodyB.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - tMat = cc.bodyA.m_xf.R; - for (i = 0; - i < cc.pointCount; ++i) { - tVec = cc.points[i].localPoint; - clipPointX = cc.bodyA.m_xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y); - clipPointY = cc.bodyA.m_xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y); - this.m_separations[i] = (clipPointX - planePointX) * this.m_normal.x + (clipPointY - planePointY) * this.m_normal.y - cc.radius; - this.m_points[i].Set(clipPointX, clipPointY); - } - this.m_normal.x *= (-1); - this.m_normal.y *= (-1); - } - break; - } - } - Box2D.postDefs.push(function () { - Box2D.Dynamics.Contacts.b2PositionSolverManifold.circlePointA = new b2Vec2(); - Box2D.Dynamics.Contacts.b2PositionSolverManifold.circlePointB = new b2Vec2(); - }); -})(); -(function () { - var b2Body = Box2D.Dynamics.b2Body, - b2BodyDef = Box2D.Dynamics.b2BodyDef, - b2ContactFilter = Box2D.Dynamics.b2ContactFilter, - b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse, - b2ContactListener = Box2D.Dynamics.b2ContactListener, - b2ContactManager = Box2D.Dynamics.b2ContactManager, - b2DebugDraw = Box2D.Dynamics.b2DebugDraw, - b2DestructionListener = Box2D.Dynamics.b2DestructionListener, - b2FilterData = Box2D.Dynamics.b2FilterData, - b2Fixture = Box2D.Dynamics.b2Fixture, - b2FixtureDef = Box2D.Dynamics.b2FixtureDef, - b2Island = Box2D.Dynamics.b2Island, - b2TimeStep = Box2D.Dynamics.b2TimeStep, - b2World = Box2D.Dynamics.b2World, - b2Mat22 = Box2D.Common.Math.b2Mat22, - b2Mat33 = Box2D.Common.Math.b2Mat33, - b2Math = Box2D.Common.Math.b2Math, - b2Sweep = Box2D.Common.Math.b2Sweep, - b2Transform = Box2D.Common.Math.b2Transform, - b2Vec2 = Box2D.Common.Math.b2Vec2, - b2Vec3 = Box2D.Common.Math.b2Vec3, - b2Color = Box2D.Common.b2Color, - b2internal = Box2D.Common.b2internal, - b2Settings = Box2D.Common.b2Settings, - b2CircleShape = Box2D.Collision.Shapes.b2CircleShape, - b2EdgeChainDef = Box2D.Collision.Shapes.b2EdgeChainDef, - b2EdgeShape = Box2D.Collision.Shapes.b2EdgeShape, - b2MassData = Box2D.Collision.Shapes.b2MassData, - b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape, - b2Shape = Box2D.Collision.Shapes.b2Shape, - b2BuoyancyController = Box2D.Dynamics.Controllers.b2BuoyancyController, - b2ConstantAccelController = Box2D.Dynamics.Controllers.b2ConstantAccelController, - b2ConstantForceController = Box2D.Dynamics.Controllers.b2ConstantForceController, - b2Controller = Box2D.Dynamics.Controllers.b2Controller, - b2ControllerEdge = Box2D.Dynamics.Controllers.b2ControllerEdge, - b2GravityController = Box2D.Dynamics.Controllers.b2GravityController, - b2TensorDampingController = Box2D.Dynamics.Controllers.b2TensorDampingController; - - Box2D.inherit(b2BuoyancyController, Box2D.Dynamics.Controllers.b2Controller); - b2BuoyancyController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype; - b2BuoyancyController.b2BuoyancyController = function () { - Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments); - this.normal = new b2Vec2(0, (-1)); - this.offset = 0; - this.density = 0; - this.velocity = new b2Vec2(0, 0); - this.linearDrag = 2; - this.angularDrag = 1; - this.useDensity = false; - this.useWorldGravity = true; - this.gravity = null; - }; - b2BuoyancyController.prototype.Step = function (step) { - if (!this.m_bodyList) return; - if (this.useWorldGravity) { - this.gravity = this.GetWorld().GetGravity().Copy(); - } - for (var i = this.m_bodyList; i; i = i.nextBody) { - var body = i.body; - if (body.IsAwake() == false) { - continue; - } - var areac = new b2Vec2(); - var massc = new b2Vec2(); - var area = 0.0; - var mass = 0.0; - for (var fixture = body.GetFixtureList(); fixture; fixture = fixture.GetNext()) { - var sc = new b2Vec2(); - var sarea = fixture.GetShape().ComputeSubmergedArea(this.normal, this.offset, body.GetTransform(), sc); - area += sarea; - areac.x += sarea * sc.x; - areac.y += sarea * sc.y; - var shapeDensity = 0; - if (this.useDensity) { - shapeDensity = 1; - } - else { - shapeDensity = 1; - } - mass += sarea * shapeDensity; - massc.x += sarea * sc.x * shapeDensity; - massc.y += sarea * sc.y * shapeDensity; - } - areac.x /= area; - areac.y /= area; - massc.x /= mass; - massc.y /= mass; - if (area < Number.MIN_VALUE) continue; - var buoyancyForce = this.gravity.GetNegative(); - buoyancyForce.Multiply(this.density * area); - body.ApplyForce(buoyancyForce, massc); - var dragForce = body.GetLinearVelocityFromWorldPoint(areac); - dragForce.Subtract(this.velocity); - dragForce.Multiply((-this.linearDrag * area)); - body.ApplyForce(dragForce, areac); - body.ApplyTorque((-body.GetInertia() / body.GetMass() * area * body.GetAngularVelocity() * this.angularDrag)); - } - } - b2BuoyancyController.prototype.Draw = function (debugDraw) { - var r = 1000; - var p1 = new b2Vec2(); - var p2 = new b2Vec2(); - p1.x = this.normal.x * this.offset + this.normal.y * r; - p1.y = this.normal.y * this.offset - this.normal.x * r; - p2.x = this.normal.x * this.offset - this.normal.y * r; - p2.y = this.normal.y * this.offset + this.normal.x * r; - var color = new b2Color(0, 0, 1); - debugDraw.DrawSegment(p1, p2, color); - } - Box2D.inherit(b2ConstantAccelController, Box2D.Dynamics.Controllers.b2Controller); - b2ConstantAccelController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype; - b2ConstantAccelController.b2ConstantAccelController = function () { - Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments); - this.A = new b2Vec2(0, 0); - }; - b2ConstantAccelController.prototype.Step = function (step) { - var smallA = new b2Vec2(this.A.x * step.dt, this.A.y * step.dt); - for (var i = this.m_bodyList; i; i = i.nextBody) { - var body = i.body; - if (!body.IsAwake()) continue; - body.SetLinearVelocity(new b2Vec2(body.GetLinearVelocity().x + smallA.x, body.GetLinearVelocity().y + smallA.y)); - } - } - Box2D.inherit(b2ConstantForceController, Box2D.Dynamics.Controllers.b2Controller); - b2ConstantForceController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype; - b2ConstantForceController.b2ConstantForceController = function () { - Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments); - this.F = new b2Vec2(0, 0); - }; - b2ConstantForceController.prototype.Step = function (step) { - for (var i = this.m_bodyList; i; i = i.nextBody) { - var body = i.body; - if (!body.IsAwake()) continue; - body.ApplyForce(this.F, body.GetWorldCenter()); - } - } - b2Controller.b2Controller = function () {}; - b2Controller.prototype.Step = function (step) {} - b2Controller.prototype.Draw = function (debugDraw) {} - b2Controller.prototype.AddBody = function (body) { - var edge = new b2ControllerEdge(); - edge.controller = this; - edge.body = body; - edge.nextBody = this.m_bodyList; - edge.prevBody = null; - this.m_bodyList = edge; - if (edge.nextBody) edge.nextBody.prevBody = edge; - this.m_bodyCount++; - edge.nextController = body.m_controllerList; - edge.prevController = null; - body.m_controllerList = edge; - if (edge.nextController) edge.nextController.prevController = edge; - body.m_controllerCount++; - } - b2Controller.prototype.RemoveBody = function (body) { - var edge = body.m_controllerList; - while (edge && edge.controller != this) - edge = edge.nextController; - if (edge.prevBody) edge.prevBody.nextBody = edge.nextBody; - if (edge.nextBody) edge.nextBody.prevBody = edge.prevBody; - if (edge.nextController) edge.nextController.prevController = edge.prevController; - if (edge.prevController) edge.prevController.nextController = edge.nextController; - if (this.m_bodyList == edge) this.m_bodyList = edge.nextBody; - if (body.m_controllerList == edge) body.m_controllerList = edge.nextController; - body.m_controllerCount--; - this.m_bodyCount--; - } - b2Controller.prototype.Clear = function () { - while (this.m_bodyList) - this.RemoveBody(this.m_bodyList.body); - } - b2Controller.prototype.GetNext = function () { - return this.m_next; - } - b2Controller.prototype.GetWorld = function () { - return this.m_world; - } - b2Controller.prototype.GetBodyList = function () { - return this.m_bodyList; - } - b2ControllerEdge.b2ControllerEdge = function () {}; - Box2D.inherit(b2GravityController, Box2D.Dynamics.Controllers.b2Controller); - b2GravityController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype; - b2GravityController.b2GravityController = function () { - Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments); - this.G = 1; - this.invSqr = true; - }; - b2GravityController.prototype.Step = function (step) { - var i = null; - var body1 = null; - var p1 = null; - var mass1 = 0; - var j = null; - var body2 = null; - var p2 = null; - var dx = 0; - var dy = 0; - var r2 = 0; - var f = null; - if (this.invSqr) { - for (i = this.m_bodyList; - i; i = i.nextBody) { - body1 = i.body; - p1 = body1.GetWorldCenter(); - mass1 = body1.GetMass(); - for (j = this.m_bodyList; - j != i; j = j.nextBody) { - body2 = j.body; - p2 = body2.GetWorldCenter(); - dx = p2.x - p1.x; - dy = p2.y - p1.y; - r2 = dx * dx + dy * dy; - if (r2 < Number.MIN_VALUE) continue; - f = new b2Vec2(dx, dy); - f.Multiply(this.G / r2 / Math.sqrt(r2) * mass1 * body2.GetMass()); - if (body1.IsAwake()) body1.ApplyForce(f, p1); - f.Multiply((-1)); - if (body2.IsAwake()) body2.ApplyForce(f, p2); - } - } - } - else { - for (i = this.m_bodyList; - i; i = i.nextBody) { - body1 = i.body; - p1 = body1.GetWorldCenter(); - mass1 = body1.GetMass(); - for (j = this.m_bodyList; - j != i; j = j.nextBody) { - body2 = j.body; - p2 = body2.GetWorldCenter(); - dx = p2.x - p1.x; - dy = p2.y - p1.y; - r2 = dx * dx + dy * dy; - if (r2 < Number.MIN_VALUE) continue; - f = new b2Vec2(dx, dy); - f.Multiply(this.G / r2 * mass1 * body2.GetMass()); - if (body1.IsAwake()) body1.ApplyForce(f, p1); - f.Multiply((-1)); - if (body2.IsAwake()) body2.ApplyForce(f, p2); - } - } - } - } - Box2D.inherit(b2TensorDampingController, Box2D.Dynamics.Controllers.b2Controller); - b2TensorDampingController.prototype.__super = Box2D.Dynamics.Controllers.b2Controller.prototype; - b2TensorDampingController.b2TensorDampingController = function () { - Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this, arguments); - this.T = new b2Mat22(); - this.maxTimestep = 0; - }; - b2TensorDampingController.prototype.SetAxisAligned = function (xDamping, yDamping) { - if (xDamping === undefined) xDamping = 0; - if (yDamping === undefined) yDamping = 0; - this.T.col1.x = (-xDamping); - this.T.col1.y = 0; - this.T.col2.x = 0; - this.T.col2.y = (-yDamping); - if (xDamping > 0 || yDamping > 0) { - this.maxTimestep = 1 / Math.max(xDamping, yDamping); - } - else { - this.maxTimestep = 0; - } - } - b2TensorDampingController.prototype.Step = function (step) { - var timestep = step.dt; - if (timestep <= Number.MIN_VALUE) return; - if (timestep > this.maxTimestep && this.maxTimestep > 0) timestep = this.maxTimestep; - for (var i = this.m_bodyList; i; i = i.nextBody) { - var body = i.body; - if (!body.IsAwake()) { - continue; - } - var damping = body.GetWorldVector(b2Math.MulMV(this.T, body.GetLocalVector(body.GetLinearVelocity()))); - body.SetLinearVelocity(new b2Vec2(body.GetLinearVelocity().x + damping.x * timestep, body.GetLinearVelocity().y + damping.y * timestep)); - } - } -})(); -(function () { - var b2Color = Box2D.Common.b2Color, - b2internal = Box2D.Common.b2internal, - b2Settings = Box2D.Common.b2Settings, - b2Mat22 = Box2D.Common.Math.b2Mat22, - b2Mat33 = Box2D.Common.Math.b2Mat33, - b2Math = Box2D.Common.Math.b2Math, - b2Sweep = Box2D.Common.Math.b2Sweep, - b2Transform = Box2D.Common.Math.b2Transform, - b2Vec2 = Box2D.Common.Math.b2Vec2, - b2Vec3 = Box2D.Common.Math.b2Vec3, - b2DistanceJoint = Box2D.Dynamics.Joints.b2DistanceJoint, - b2DistanceJointDef = Box2D.Dynamics.Joints.b2DistanceJointDef, - b2FrictionJoint = Box2D.Dynamics.Joints.b2FrictionJoint, - b2FrictionJointDef = Box2D.Dynamics.Joints.b2FrictionJointDef, - b2GearJoint = Box2D.Dynamics.Joints.b2GearJoint, - b2GearJointDef = Box2D.Dynamics.Joints.b2GearJointDef, - b2Jacobian = Box2D.Dynamics.Joints.b2Jacobian, - b2Joint = Box2D.Dynamics.Joints.b2Joint, - b2JointDef = Box2D.Dynamics.Joints.b2JointDef, - b2JointEdge = Box2D.Dynamics.Joints.b2JointEdge, - b2LineJoint = Box2D.Dynamics.Joints.b2LineJoint, - b2LineJointDef = Box2D.Dynamics.Joints.b2LineJointDef, - b2MouseJoint = Box2D.Dynamics.Joints.b2MouseJoint, - b2MouseJointDef = Box2D.Dynamics.Joints.b2MouseJointDef, - b2PrismaticJoint = Box2D.Dynamics.Joints.b2PrismaticJoint, - b2PrismaticJointDef = Box2D.Dynamics.Joints.b2PrismaticJointDef, - b2PulleyJoint = Box2D.Dynamics.Joints.b2PulleyJoint, - b2PulleyJointDef = Box2D.Dynamics.Joints.b2PulleyJointDef, - b2RevoluteJoint = Box2D.Dynamics.Joints.b2RevoluteJoint, - b2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef, - b2WeldJoint = Box2D.Dynamics.Joints.b2WeldJoint, - b2WeldJointDef = Box2D.Dynamics.Joints.b2WeldJointDef, - b2Body = Box2D.Dynamics.b2Body, - b2BodyDef = Box2D.Dynamics.b2BodyDef, - b2ContactFilter = Box2D.Dynamics.b2ContactFilter, - b2ContactImpulse = Box2D.Dynamics.b2ContactImpulse, - b2ContactListener = Box2D.Dynamics.b2ContactListener, - b2ContactManager = Box2D.Dynamics.b2ContactManager, - b2DebugDraw = Box2D.Dynamics.b2DebugDraw, - b2DestructionListener = Box2D.Dynamics.b2DestructionListener, - b2FilterData = Box2D.Dynamics.b2FilterData, - b2Fixture = Box2D.Dynamics.b2Fixture, - b2FixtureDef = Box2D.Dynamics.b2FixtureDef, - b2Island = Box2D.Dynamics.b2Island, - b2TimeStep = Box2D.Dynamics.b2TimeStep, - b2World = Box2D.Dynamics.b2World; - - Box2D.inherit(b2DistanceJoint, Box2D.Dynamics.Joints.b2Joint); - b2DistanceJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; - b2DistanceJoint.b2DistanceJoint = function () { - Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); - this.m_localAnchor1 = new b2Vec2(); - this.m_localAnchor2 = new b2Vec2(); - this.m_u = new b2Vec2(); - }; - b2DistanceJoint.prototype.GetAnchorA = function () { - return this.m_bodyA.GetWorldPoint(this.m_localAnchor1); - } - b2DistanceJoint.prototype.GetAnchorB = function () { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor2); - } - b2DistanceJoint.prototype.GetReactionForce = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return new b2Vec2(inv_dt * this.m_impulse * this.m_u.x, inv_dt * this.m_impulse * this.m_u.y); - } - b2DistanceJoint.prototype.GetReactionTorque = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return 0.0; - } - b2DistanceJoint.prototype.GetLength = function () { - return this.m_length; - } - b2DistanceJoint.prototype.SetLength = function (length) { - if (length === undefined) length = 0; - this.m_length = length; - } - b2DistanceJoint.prototype.GetFrequency = function () { - return this.m_frequencyHz; - } - b2DistanceJoint.prototype.SetFrequency = function (hz) { - if (hz === undefined) hz = 0; - this.m_frequencyHz = hz; - } - b2DistanceJoint.prototype.GetDampingRatio = function () { - return this.m_dampingRatio; - } - b2DistanceJoint.prototype.SetDampingRatio = function (ratio) { - if (ratio === undefined) ratio = 0; - this.m_dampingRatio = ratio; - } - b2DistanceJoint.prototype.b2DistanceJoint = function (def) { - this.__super.b2Joint.call(this, def); - var tMat; - var tX = 0; - var tY = 0; - this.m_localAnchor1.SetV(def.localAnchorA); - this.m_localAnchor2.SetV(def.localAnchorB); - this.m_length = def.length; - this.m_frequencyHz = def.frequencyHz; - this.m_dampingRatio = def.dampingRatio; - this.m_impulse = 0.0; - this.m_gamma = 0.0; - this.m_bias = 0.0; - } - b2DistanceJoint.prototype.InitVelocityConstraints = function (step) { - var tMat; - var tX = 0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - this.m_u.x = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; - this.m_u.y = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; - var length = Math.sqrt(this.m_u.x * this.m_u.x + this.m_u.y * this.m_u.y); - if (length > b2Settings.b2_linearSlop) { - this.m_u.Multiply(1.0 / length); - } - else { - this.m_u.SetZero(); - } - var cr1u = (r1X * this.m_u.y - r1Y * this.m_u.x); - var cr2u = (r2X * this.m_u.y - r2Y * this.m_u.x); - var invMass = bA.m_invMass + bA.m_invI * cr1u * cr1u + bB.m_invMass + bB.m_invI * cr2u * cr2u; - this.m_mass = invMass != 0.0 ? 1.0 / invMass : 0.0; - if (this.m_frequencyHz > 0.0) { - var C = length - this.m_length; - var omega = 2.0 * Math.PI * this.m_frequencyHz; - var d = 2.0 * this.m_mass * this.m_dampingRatio * omega; - var k = this.m_mass * omega * omega; - this.m_gamma = step.dt * (d + step.dt * k); - this.m_gamma = this.m_gamma != 0.0 ? 1 / this.m_gamma : 0.0; - this.m_bias = C * step.dt * k * this.m_gamma; - this.m_mass = invMass + this.m_gamma; - this.m_mass = this.m_mass != 0.0 ? 1.0 / this.m_mass : 0.0; - } - if (step.warmStarting) { - this.m_impulse *= step.dtRatio; - var PX = this.m_impulse * this.m_u.x; - var PY = this.m_impulse * this.m_u.y; - bA.m_linearVelocity.x -= bA.m_invMass * PX; - bA.m_linearVelocity.y -= bA.m_invMass * PY; - bA.m_angularVelocity -= bA.m_invI * (r1X * PY - r1Y * PX); - bB.m_linearVelocity.x += bB.m_invMass * PX; - bB.m_linearVelocity.y += bB.m_invMass * PY; - bB.m_angularVelocity += bB.m_invI * (r2X * PY - r2Y * PX); - } - else { - this.m_impulse = 0.0; - } - } - b2DistanceJoint.prototype.SolveVelocityConstraints = function (step) { - var tMat; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var v1X = bA.m_linearVelocity.x + ((-bA.m_angularVelocity * r1Y)); - var v1Y = bA.m_linearVelocity.y + (bA.m_angularVelocity * r1X); - var v2X = bB.m_linearVelocity.x + ((-bB.m_angularVelocity * r2Y)); - var v2Y = bB.m_linearVelocity.y + (bB.m_angularVelocity * r2X); - var Cdot = (this.m_u.x * (v2X - v1X) + this.m_u.y * (v2Y - v1Y)); - var impulse = (-this.m_mass * (Cdot + this.m_bias + this.m_gamma * this.m_impulse)); - this.m_impulse += impulse; - var PX = impulse * this.m_u.x; - var PY = impulse * this.m_u.y; - bA.m_linearVelocity.x -= bA.m_invMass * PX; - bA.m_linearVelocity.y -= bA.m_invMass * PY; - bA.m_angularVelocity -= bA.m_invI * (r1X * PY - r1Y * PX); - bB.m_linearVelocity.x += bB.m_invMass * PX; - bB.m_linearVelocity.y += bB.m_invMass * PY; - bB.m_angularVelocity += bB.m_invI * (r2X * PY - r2Y * PX); - } - b2DistanceJoint.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - var tMat; - if (this.m_frequencyHz > 0.0) { - return true; - } - var bA = this.m_bodyA; - var bB = this.m_bodyB; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; - var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; - var length = Math.sqrt(dX * dX + dY * dY); - dX /= length; - dY /= length; - var C = length - this.m_length; - C = b2Math.Clamp(C, (-b2Settings.b2_maxLinearCorrection), b2Settings.b2_maxLinearCorrection); - var impulse = (-this.m_mass * C); - this.m_u.Set(dX, dY); - var PX = impulse * this.m_u.x; - var PY = impulse * this.m_u.y; - bA.m_sweep.c.x -= bA.m_invMass * PX; - bA.m_sweep.c.y -= bA.m_invMass * PY; - bA.m_sweep.a -= bA.m_invI * (r1X * PY - r1Y * PX); - bB.m_sweep.c.x += bB.m_invMass * PX; - bB.m_sweep.c.y += bB.m_invMass * PY; - bB.m_sweep.a += bB.m_invI * (r2X * PY - r2Y * PX); - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - return b2Math.Abs(C) < b2Settings.b2_linearSlop; - } - Box2D.inherit(b2DistanceJointDef, Box2D.Dynamics.Joints.b2JointDef); - b2DistanceJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; - b2DistanceJointDef.b2DistanceJointDef = function () { - Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); - this.localAnchorA = new b2Vec2(); - this.localAnchorB = new b2Vec2(); - }; - b2DistanceJointDef.prototype.b2DistanceJointDef = function () { - this.__super.b2JointDef.call(this); - this.type = b2Joint.e_distanceJoint; - this.length = 1.0; - this.frequencyHz = 0.0; - this.dampingRatio = 0.0; - } - b2DistanceJointDef.prototype.Initialize = function (bA, bB, anchorA, anchorB) { - this.bodyA = bA; - this.bodyB = bB; - this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchorA)); - this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchorB)); - var dX = anchorB.x - anchorA.x; - var dY = anchorB.y - anchorA.y; - this.length = Math.sqrt(dX * dX + dY * dY); - this.frequencyHz = 0.0; - this.dampingRatio = 0.0; - } - Box2D.inherit(b2FrictionJoint, Box2D.Dynamics.Joints.b2Joint); - b2FrictionJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; - b2FrictionJoint.b2FrictionJoint = function () { - Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); - this.m_localAnchorA = new b2Vec2(); - this.m_localAnchorB = new b2Vec2(); - this.m_linearMass = new b2Mat22(); - this.m_linearImpulse = new b2Vec2(); - }; - b2FrictionJoint.prototype.GetAnchorA = function () { - return this.m_bodyA.GetWorldPoint(this.m_localAnchorA); - } - b2FrictionJoint.prototype.GetAnchorB = function () { - return this.m_bodyB.GetWorldPoint(this.m_localAnchorB); - } - b2FrictionJoint.prototype.GetReactionForce = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return new b2Vec2(inv_dt * this.m_linearImpulse.x, inv_dt * this.m_linearImpulse.y); - } - b2FrictionJoint.prototype.GetReactionTorque = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return inv_dt * this.m_angularImpulse; - } - b2FrictionJoint.prototype.SetMaxForce = function (force) { - if (force === undefined) force = 0; - this.m_maxForce = force; - } - b2FrictionJoint.prototype.GetMaxForce = function () { - return this.m_maxForce; - } - b2FrictionJoint.prototype.SetMaxTorque = function (torque) { - if (torque === undefined) torque = 0; - this.m_maxTorque = torque; - } - b2FrictionJoint.prototype.GetMaxTorque = function () { - return this.m_maxTorque; - } - b2FrictionJoint.prototype.b2FrictionJoint = function (def) { - this.__super.b2Joint.call(this, def); - this.m_localAnchorA.SetV(def.localAnchorA); - this.m_localAnchorB.SetV(def.localAnchorB); - this.m_linearMass.SetZero(); - this.m_angularMass = 0.0; - this.m_linearImpulse.SetZero(); - this.m_angularImpulse = 0.0; - this.m_maxForce = def.maxForce; - this.m_maxTorque = def.maxTorque; - } - b2FrictionJoint.prototype.InitVelocityConstraints = function (step) { - var tMat; - var tX = 0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - tMat = bA.m_xf.R; - var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; - var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * rAX + tMat.col2.x * rAY); - rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY); - rAX = tX; - tMat = bB.m_xf.R; - var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; - var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * rBX + tMat.col2.x * rBY); - rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY); - rBX = tX; - var mA = bA.m_invMass; - var mB = bB.m_invMass; - var iA = bA.m_invI; - var iB = bB.m_invI; - var K = new b2Mat22(); - K.col1.x = mA + mB; - K.col2.x = 0.0; - K.col1.y = 0.0; - K.col2.y = mA + mB; - K.col1.x += iA * rAY * rAY; - K.col2.x += (-iA * rAX * rAY); - K.col1.y += (-iA * rAX * rAY); - K.col2.y += iA * rAX * rAX; - K.col1.x += iB * rBY * rBY; - K.col2.x += (-iB * rBX * rBY); - K.col1.y += (-iB * rBX * rBY); - K.col2.y += iB * rBX * rBX; - K.GetInverse(this.m_linearMass); - this.m_angularMass = iA + iB; - if (this.m_angularMass > 0.0) { - this.m_angularMass = 1.0 / this.m_angularMass; - } - if (step.warmStarting) { - this.m_linearImpulse.x *= step.dtRatio; - this.m_linearImpulse.y *= step.dtRatio; - this.m_angularImpulse *= step.dtRatio; - var P = this.m_linearImpulse; - bA.m_linearVelocity.x -= mA * P.x; - bA.m_linearVelocity.y -= mA * P.y; - bA.m_angularVelocity -= iA * (rAX * P.y - rAY * P.x + this.m_angularImpulse); - bB.m_linearVelocity.x += mB * P.x; - bB.m_linearVelocity.y += mB * P.y; - bB.m_angularVelocity += iB * (rBX * P.y - rBY * P.x + this.m_angularImpulse); - } - else { - this.m_linearImpulse.SetZero(); - this.m_angularImpulse = 0.0; - } - } - b2FrictionJoint.prototype.SolveVelocityConstraints = function (step) { - var tMat; - var tX = 0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var vA = bA.m_linearVelocity; - var wA = bA.m_angularVelocity; - var vB = bB.m_linearVelocity; - var wB = bB.m_angularVelocity; - var mA = bA.m_invMass; - var mB = bB.m_invMass; - var iA = bA.m_invI; - var iB = bB.m_invI; - tMat = bA.m_xf.R; - var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; - var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * rAX + tMat.col2.x * rAY); - rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY); - rAX = tX; - tMat = bB.m_xf.R; - var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; - var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * rBX + tMat.col2.x * rBY); - rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY); - rBX = tX; - var maxImpulse = 0; { - var Cdot = wB - wA; - var impulse = (-this.m_angularMass * Cdot); - var oldImpulse = this.m_angularImpulse; - maxImpulse = step.dt * this.m_maxTorque; - this.m_angularImpulse = b2Math.Clamp(this.m_angularImpulse + impulse, (-maxImpulse), maxImpulse); - impulse = this.m_angularImpulse - oldImpulse; - wA -= iA * impulse; - wB += iB * impulse; - } { - var CdotX = vB.x - wB * rBY - vA.x + wA * rAY; - var CdotY = vB.y + wB * rBX - vA.y - wA * rAX; - var impulseV = b2Math.MulMV(this.m_linearMass, new b2Vec2((-CdotX), (-CdotY))); - var oldImpulseV = this.m_linearImpulse.Copy(); - this.m_linearImpulse.Add(impulseV); - maxImpulse = step.dt * this.m_maxForce; - if (this.m_linearImpulse.LengthSquared() > maxImpulse * maxImpulse) { - this.m_linearImpulse.Normalize(); - this.m_linearImpulse.Multiply(maxImpulse); - } - impulseV = b2Math.SubtractVV(this.m_linearImpulse, oldImpulseV); - vA.x -= mA * impulseV.x; - vA.y -= mA * impulseV.y; - wA -= iA * (rAX * impulseV.y - rAY * impulseV.x); - vB.x += mB * impulseV.x; - vB.y += mB * impulseV.y; - wB += iB * (rBX * impulseV.y - rBY * impulseV.x); - } - bA.m_angularVelocity = wA; - bB.m_angularVelocity = wB; - } - b2FrictionJoint.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - return true; - } - Box2D.inherit(b2FrictionJointDef, Box2D.Dynamics.Joints.b2JointDef); - b2FrictionJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; - b2FrictionJointDef.b2FrictionJointDef = function () { - Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); - this.localAnchorA = new b2Vec2(); - this.localAnchorB = new b2Vec2(); - }; - b2FrictionJointDef.prototype.b2FrictionJointDef = function () { - this.__super.b2JointDef.call(this); - this.type = b2Joint.e_frictionJoint; - this.maxForce = 0.0; - this.maxTorque = 0.0; - } - b2FrictionJointDef.prototype.Initialize = function (bA, bB, anchor) { - this.bodyA = bA; - this.bodyB = bB; - this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchor)); - this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchor)); - } - Box2D.inherit(b2GearJoint, Box2D.Dynamics.Joints.b2Joint); - b2GearJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; - b2GearJoint.b2GearJoint = function () { - Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); - this.m_groundAnchor1 = new b2Vec2(); - this.m_groundAnchor2 = new b2Vec2(); - this.m_localAnchor1 = new b2Vec2(); - this.m_localAnchor2 = new b2Vec2(); - this.m_J = new b2Jacobian(); - }; - b2GearJoint.prototype.GetAnchorA = function () { - return this.m_bodyA.GetWorldPoint(this.m_localAnchor1); - } - b2GearJoint.prototype.GetAnchorB = function () { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor2); - } - b2GearJoint.prototype.GetReactionForce = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return new b2Vec2(inv_dt * this.m_impulse * this.m_J.linearB.x, inv_dt * this.m_impulse * this.m_J.linearB.y); - } - b2GearJoint.prototype.GetReactionTorque = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - var tMat = this.m_bodyB.m_xf.R; - var rX = this.m_localAnchor1.x - this.m_bodyB.m_sweep.localCenter.x; - var rY = this.m_localAnchor1.y - this.m_bodyB.m_sweep.localCenter.y; - var tX = tMat.col1.x * rX + tMat.col2.x * rY; - rY = tMat.col1.y * rX + tMat.col2.y * rY; - rX = tX; - var PX = this.m_impulse * this.m_J.linearB.x; - var PY = this.m_impulse * this.m_J.linearB.y; - return inv_dt * (this.m_impulse * this.m_J.angularB - rX * PY + rY * PX); - } - b2GearJoint.prototype.GetRatio = function () { - return this.m_ratio; - } - b2GearJoint.prototype.SetRatio = function (ratio) { - if (ratio === undefined) ratio = 0; - this.m_ratio = ratio; - } - b2GearJoint.prototype.b2GearJoint = function (def) { - this.__super.b2Joint.call(this, def); - var type1 = parseInt(def.joint1.m_type); - var type2 = parseInt(def.joint2.m_type); - this.m_revolute1 = null; - this.m_prismatic1 = null; - this.m_revolute2 = null; - this.m_prismatic2 = null; - var coordinate1 = 0; - var coordinate2 = 0; - this.m_ground1 = def.joint1.GetBodyA(); - this.m_bodyA = def.joint1.GetBodyB(); - if (type1 == b2Joint.e_revoluteJoint) { - this.m_revolute1 = (def.joint1 instanceof b2RevoluteJoint ? def.joint1 : null); - this.m_groundAnchor1.SetV(this.m_revolute1.m_localAnchor1); - this.m_localAnchor1.SetV(this.m_revolute1.m_localAnchor2); - coordinate1 = this.m_revolute1.GetJointAngle(); - } - else { - this.m_prismatic1 = (def.joint1 instanceof b2PrismaticJoint ? def.joint1 : null); - this.m_groundAnchor1.SetV(this.m_prismatic1.m_localAnchor1); - this.m_localAnchor1.SetV(this.m_prismatic1.m_localAnchor2); - coordinate1 = this.m_prismatic1.GetJointTranslation(); - } - this.m_ground2 = def.joint2.GetBodyA(); - this.m_bodyB = def.joint2.GetBodyB(); - if (type2 == b2Joint.e_revoluteJoint) { - this.m_revolute2 = (def.joint2 instanceof b2RevoluteJoint ? def.joint2 : null); - this.m_groundAnchor2.SetV(this.m_revolute2.m_localAnchor1); - this.m_localAnchor2.SetV(this.m_revolute2.m_localAnchor2); - coordinate2 = this.m_revolute2.GetJointAngle(); - } - else { - this.m_prismatic2 = (def.joint2 instanceof b2PrismaticJoint ? def.joint2 : null); - this.m_groundAnchor2.SetV(this.m_prismatic2.m_localAnchor1); - this.m_localAnchor2.SetV(this.m_prismatic2.m_localAnchor2); - coordinate2 = this.m_prismatic2.GetJointTranslation(); - } - this.m_ratio = def.ratio; - this.m_constant = coordinate1 + this.m_ratio * coordinate2; - this.m_impulse = 0.0; - } - b2GearJoint.prototype.InitVelocityConstraints = function (step) { - var g1 = this.m_ground1; - var g2 = this.m_ground2; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var ugX = 0; - var ugY = 0; - var rX = 0; - var rY = 0; - var tMat; - var tVec; - var crug = 0; - var tX = 0; - var K = 0.0; - this.m_J.SetZero(); - if (this.m_revolute1) { - this.m_J.angularA = (-1.0); - K += bA.m_invI; - } - else { - tMat = g1.m_xf.R; - tVec = this.m_prismatic1.m_localXAxis1; - ugX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - ugY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = bA.m_xf.R; - rX = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - rY = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = tMat.col1.x * rX + tMat.col2.x * rY; - rY = tMat.col1.y * rX + tMat.col2.y * rY; - rX = tX; - crug = rX * ugY - rY * ugX; - this.m_J.linearA.Set((-ugX), (-ugY)); - this.m_J.angularA = (-crug); - K += bA.m_invMass + bA.m_invI * crug * crug; - } - if (this.m_revolute2) { - this.m_J.angularB = (-this.m_ratio); - K += this.m_ratio * this.m_ratio * bB.m_invI; - } - else { - tMat = g2.m_xf.R; - tVec = this.m_prismatic2.m_localXAxis1; - ugX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; - ugY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; - tMat = bB.m_xf.R; - rX = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - rY = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = tMat.col1.x * rX + tMat.col2.x * rY; - rY = tMat.col1.y * rX + tMat.col2.y * rY; - rX = tX; - crug = rX * ugY - rY * ugX; - this.m_J.linearB.Set((-this.m_ratio * ugX), (-this.m_ratio * ugY)); - this.m_J.angularB = (-this.m_ratio * crug); - K += this.m_ratio * this.m_ratio * (bB.m_invMass + bB.m_invI * crug * crug); - } - this.m_mass = K > 0.0 ? 1.0 / K : 0.0; - if (step.warmStarting) { - bA.m_linearVelocity.x += bA.m_invMass * this.m_impulse * this.m_J.linearA.x; - bA.m_linearVelocity.y += bA.m_invMass * this.m_impulse * this.m_J.linearA.y; - bA.m_angularVelocity += bA.m_invI * this.m_impulse * this.m_J.angularA; - bB.m_linearVelocity.x += bB.m_invMass * this.m_impulse * this.m_J.linearB.x; - bB.m_linearVelocity.y += bB.m_invMass * this.m_impulse * this.m_J.linearB.y; - bB.m_angularVelocity += bB.m_invI * this.m_impulse * this.m_J.angularB; - } - else { - this.m_impulse = 0.0; - } - } - b2GearJoint.prototype.SolveVelocityConstraints = function (step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var Cdot = this.m_J.Compute(bA.m_linearVelocity, bA.m_angularVelocity, bB.m_linearVelocity, bB.m_angularVelocity); - var impulse = (-this.m_mass * Cdot); - this.m_impulse += impulse; - bA.m_linearVelocity.x += bA.m_invMass * impulse * this.m_J.linearA.x; - bA.m_linearVelocity.y += bA.m_invMass * impulse * this.m_J.linearA.y; - bA.m_angularVelocity += bA.m_invI * impulse * this.m_J.angularA; - bB.m_linearVelocity.x += bB.m_invMass * impulse * this.m_J.linearB.x; - bB.m_linearVelocity.y += bB.m_invMass * impulse * this.m_J.linearB.y; - bB.m_angularVelocity += bB.m_invI * impulse * this.m_J.angularB; - } - b2GearJoint.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - var linearError = 0.0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var coordinate1 = 0; - var coordinate2 = 0; - if (this.m_revolute1) { - coordinate1 = this.m_revolute1.GetJointAngle(); - } - else { - coordinate1 = this.m_prismatic1.GetJointTranslation(); - } - if (this.m_revolute2) { - coordinate2 = this.m_revolute2.GetJointAngle(); - } - else { - coordinate2 = this.m_prismatic2.GetJointTranslation(); - } - var C = this.m_constant - (coordinate1 + this.m_ratio * coordinate2); - var impulse = (-this.m_mass * C); - bA.m_sweep.c.x += bA.m_invMass * impulse * this.m_J.linearA.x; - bA.m_sweep.c.y += bA.m_invMass * impulse * this.m_J.linearA.y; - bA.m_sweep.a += bA.m_invI * impulse * this.m_J.angularA; - bB.m_sweep.c.x += bB.m_invMass * impulse * this.m_J.linearB.x; - bB.m_sweep.c.y += bB.m_invMass * impulse * this.m_J.linearB.y; - bB.m_sweep.a += bB.m_invI * impulse * this.m_J.angularB; - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - return linearError < b2Settings.b2_linearSlop; - } - Box2D.inherit(b2GearJointDef, Box2D.Dynamics.Joints.b2JointDef); - b2GearJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; - b2GearJointDef.b2GearJointDef = function () { - Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); - }; - b2GearJointDef.prototype.b2GearJointDef = function () { - this.__super.b2JointDef.call(this); - this.type = b2Joint.e_gearJoint; - this.joint1 = null; - this.joint2 = null; - this.ratio = 1.0; - } - b2Jacobian.b2Jacobian = function () { - this.linearA = new b2Vec2(); - this.linearB = new b2Vec2(); - }; - b2Jacobian.prototype.SetZero = function () { - this.linearA.SetZero(); - this.angularA = 0.0; - this.linearB.SetZero(); - this.angularB = 0.0; - } - b2Jacobian.prototype.Set = function (x1, a1, x2, a2) { - if (a1 === undefined) a1 = 0; - if (a2 === undefined) a2 = 0; - this.linearA.SetV(x1); - this.angularA = a1; - this.linearB.SetV(x2); - this.angularB = a2; - } - b2Jacobian.prototype.Compute = function (x1, a1, x2, a2) { - if (a1 === undefined) a1 = 0; - if (a2 === undefined) a2 = 0; - return (this.linearA.x * x1.x + this.linearA.y * x1.y) + this.angularA * a1 + (this.linearB.x * x2.x + this.linearB.y * x2.y) + this.angularB * a2; - } - b2Joint.b2Joint = function () { - this.m_edgeA = new b2JointEdge(); - this.m_edgeB = new b2JointEdge(); - this.m_localCenterA = new b2Vec2(); - this.m_localCenterB = new b2Vec2(); - }; - b2Joint.prototype.GetType = function () { - return this.m_type; - } - b2Joint.prototype.GetAnchorA = function () { - return null; - } - b2Joint.prototype.GetAnchorB = function () { - return null; - } - b2Joint.prototype.GetReactionForce = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return null; - } - b2Joint.prototype.GetReactionTorque = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return 0.0; - } - b2Joint.prototype.GetBodyA = function () { - return this.m_bodyA; - } - b2Joint.prototype.GetBodyB = function () { - return this.m_bodyB; - } - b2Joint.prototype.GetNext = function () { - return this.m_next; - } - b2Joint.prototype.GetUserData = function () { - return this.m_userData; - } - b2Joint.prototype.SetUserData = function (data) { - this.m_userData = data; - } - b2Joint.prototype.IsActive = function () { - return this.m_bodyA.IsActive() && this.m_bodyB.IsActive(); - } - b2Joint.Create = function (def, allocator) { - var joint = null; - switch (def.type) { - case b2Joint.e_distanceJoint: - { - joint = new b2DistanceJoint((def instanceof b2DistanceJointDef ? def : null)); - } - break; - case b2Joint.e_mouseJoint: - { - joint = new b2MouseJoint((def instanceof b2MouseJointDef ? def : null)); - } - break; - case b2Joint.e_prismaticJoint: - { - joint = new b2PrismaticJoint((def instanceof b2PrismaticJointDef ? def : null)); - } - break; - case b2Joint.e_revoluteJoint: - { - joint = new b2RevoluteJoint((def instanceof b2RevoluteJointDef ? def : null)); - } - break; - case b2Joint.e_pulleyJoint: - { - joint = new b2PulleyJoint((def instanceof b2PulleyJointDef ? def : null)); - } - break; - case b2Joint.e_gearJoint: - { - joint = new b2GearJoint((def instanceof b2GearJointDef ? def : null)); - } - break; - case b2Joint.e_lineJoint: - { - joint = new b2LineJoint((def instanceof b2LineJointDef ? def : null)); - } - break; - case b2Joint.e_weldJoint: - { - joint = new b2WeldJoint((def instanceof b2WeldJointDef ? def : null)); - } - break; - case b2Joint.e_frictionJoint: - { - joint = new b2FrictionJoint((def instanceof b2FrictionJointDef ? def : null)); - } - break; - default: - break; - } - return joint; - } - b2Joint.Destroy = function (joint, allocator) {} - b2Joint.prototype.b2Joint = function (def) { - b2Settings.b2Assert(def.bodyA != def.bodyB); - this.m_type = def.type; - this.m_prev = null; - this.m_next = null; - this.m_bodyA = def.bodyA; - this.m_bodyB = def.bodyB; - this.m_collideConnected = def.collideConnected; - this.m_islandFlag = false; - this.m_userData = def.userData; - } - b2Joint.prototype.InitVelocityConstraints = function (step) {} - b2Joint.prototype.SolveVelocityConstraints = function (step) {} - b2Joint.prototype.FinalizeVelocityConstraints = function () {} - b2Joint.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - return false; - } - Box2D.postDefs.push(function () { - Box2D.Dynamics.Joints.b2Joint.e_unknownJoint = 0; - Box2D.Dynamics.Joints.b2Joint.e_revoluteJoint = 1; - Box2D.Dynamics.Joints.b2Joint.e_prismaticJoint = 2; - Box2D.Dynamics.Joints.b2Joint.e_distanceJoint = 3; - Box2D.Dynamics.Joints.b2Joint.e_pulleyJoint = 4; - Box2D.Dynamics.Joints.b2Joint.e_mouseJoint = 5; - Box2D.Dynamics.Joints.b2Joint.e_gearJoint = 6; - Box2D.Dynamics.Joints.b2Joint.e_lineJoint = 7; - Box2D.Dynamics.Joints.b2Joint.e_weldJoint = 8; - Box2D.Dynamics.Joints.b2Joint.e_frictionJoint = 9; - Box2D.Dynamics.Joints.b2Joint.e_inactiveLimit = 0; - Box2D.Dynamics.Joints.b2Joint.e_atLowerLimit = 1; - Box2D.Dynamics.Joints.b2Joint.e_atUpperLimit = 2; - Box2D.Dynamics.Joints.b2Joint.e_equalLimits = 3; - }); - b2JointDef.b2JointDef = function () {}; - b2JointDef.prototype.b2JointDef = function () { - this.type = b2Joint.e_unknownJoint; - this.userData = null; - this.bodyA = null; - this.bodyB = null; - this.collideConnected = false; - } - b2JointEdge.b2JointEdge = function () {}; - Box2D.inherit(b2LineJoint, Box2D.Dynamics.Joints.b2Joint); - b2LineJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; - b2LineJoint.b2LineJoint = function () { - Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); - this.m_localAnchor1 = new b2Vec2(); - this.m_localAnchor2 = new b2Vec2(); - this.m_localXAxis1 = new b2Vec2(); - this.m_localYAxis1 = new b2Vec2(); - this.m_axis = new b2Vec2(); - this.m_perp = new b2Vec2(); - this.m_K = new b2Mat22(); - this.m_impulse = new b2Vec2(); - }; - b2LineJoint.prototype.GetAnchorA = function () { - return this.m_bodyA.GetWorldPoint(this.m_localAnchor1); - } - b2LineJoint.prototype.GetAnchorB = function () { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor2); - } - b2LineJoint.prototype.GetReactionForce = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return new b2Vec2(inv_dt * (this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.x), inv_dt * (this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.y)); - } - b2LineJoint.prototype.GetReactionTorque = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return inv_dt * this.m_impulse.y; - } - b2LineJoint.prototype.GetJointTranslation = function () { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var p1 = bA.GetWorldPoint(this.m_localAnchor1); - var p2 = bB.GetWorldPoint(this.m_localAnchor2); - var dX = p2.x - p1.x; - var dY = p2.y - p1.y; - var axis = bA.GetWorldVector(this.m_localXAxis1); - var translation = axis.x * dX + axis.y * dY; - return translation; - } - b2LineJoint.prototype.GetJointSpeed = function () { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var p1X = bA.m_sweep.c.x + r1X; - var p1Y = bA.m_sweep.c.y + r1Y; - var p2X = bB.m_sweep.c.x + r2X; - var p2Y = bB.m_sweep.c.y + r2Y; - var dX = p2X - p1X; - var dY = p2Y - p1Y; - var axis = bA.GetWorldVector(this.m_localXAxis1); - var v1 = bA.m_linearVelocity; - var v2 = bB.m_linearVelocity; - var w1 = bA.m_angularVelocity; - var w2 = bB.m_angularVelocity; - var speed = (dX * ((-w1 * axis.y)) + dY * (w1 * axis.x)) + (axis.x * (((v2.x + ((-w2 * r2Y))) - v1.x) - ((-w1 * r1Y))) + axis.y * (((v2.y + (w2 * r2X)) - v1.y) - (w1 * r1X))); - return speed; - } - b2LineJoint.prototype.IsLimitEnabled = function () { - return this.m_enableLimit; - } - b2LineJoint.prototype.EnableLimit = function (flag) { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_enableLimit = flag; - } - b2LineJoint.prototype.GetLowerLimit = function () { - return this.m_lowerTranslation; - } - b2LineJoint.prototype.GetUpperLimit = function () { - return this.m_upperTranslation; - } - b2LineJoint.prototype.SetLimits = function (lower, upper) { - if (lower === undefined) lower = 0; - if (upper === undefined) upper = 0; - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_lowerTranslation = lower; - this.m_upperTranslation = upper; - } - b2LineJoint.prototype.IsMotorEnabled = function () { - return this.m_enableMotor; - } - b2LineJoint.prototype.EnableMotor = function (flag) { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_enableMotor = flag; - } - b2LineJoint.prototype.SetMotorSpeed = function (speed) { - if (speed === undefined) speed = 0; - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_motorSpeed = speed; - } - b2LineJoint.prototype.GetMotorSpeed = function () { - return this.m_motorSpeed; - } - b2LineJoint.prototype.SetMaxMotorForce = function (force) { - if (force === undefined) force = 0; - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_maxMotorForce = force; - } - b2LineJoint.prototype.GetMaxMotorForce = function () { - return this.m_maxMotorForce; - } - b2LineJoint.prototype.GetMotorForce = function () { - return this.m_motorImpulse; - } - b2LineJoint.prototype.b2LineJoint = function (def) { - this.__super.b2Joint.call(this, def); - var tMat; - var tX = 0; - var tY = 0; - this.m_localAnchor1.SetV(def.localAnchorA); - this.m_localAnchor2.SetV(def.localAnchorB); - this.m_localXAxis1.SetV(def.localAxisA); - this.m_localYAxis1.x = (-this.m_localXAxis1.y); - this.m_localYAxis1.y = this.m_localXAxis1.x; - this.m_impulse.SetZero(); - this.m_motorMass = 0.0; - this.m_motorImpulse = 0.0; - this.m_lowerTranslation = def.lowerTranslation; - this.m_upperTranslation = def.upperTranslation; - this.m_maxMotorForce = def.maxMotorForce; - this.m_motorSpeed = def.motorSpeed; - this.m_enableLimit = def.enableLimit; - this.m_enableMotor = def.enableMotor; - this.m_limitState = b2Joint.e_inactiveLimit; - this.m_axis.SetZero(); - this.m_perp.SetZero(); - } - b2LineJoint.prototype.InitVelocityConstraints = function (step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var tX = 0; - this.m_localCenterA.SetV(bA.GetLocalCenter()); - this.m_localCenterB.SetV(bB.GetLocalCenter()); - var xf1 = bA.GetTransform(); - var xf2 = bB.GetTransform(); - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - this.m_localCenterA.x; - var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - this.m_localCenterB.x; - var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; - var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; - this.m_invMassA = bA.m_invMass; - this.m_invMassB = bB.m_invMass; - this.m_invIA = bA.m_invI; - this.m_invIB = bB.m_invI; { - this.m_axis.SetV(b2Math.MulMV(xf1.R, this.m_localXAxis1)); - this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x; - this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x; - this.m_motorMass = this.m_invMassA + this.m_invMassB + this.m_invIA * this.m_a1 * this.m_a1 + this.m_invIB * this.m_a2 * this.m_a2; - this.m_motorMass = this.m_motorMass > Number.MIN_VALUE ? 1.0 / this.m_motorMass : 0.0; - } { - this.m_perp.SetV(b2Math.MulMV(xf1.R, this.m_localYAxis1)); - this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x; - this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x; - var m1 = this.m_invMassA; - var m2 = this.m_invMassB; - var i1 = this.m_invIA; - var i2 = this.m_invIB; - this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; - this.m_K.col1.y = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2; - this.m_K.col2.x = this.m_K.col1.y; - this.m_K.col2.y = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2; - } - if (this.m_enableLimit) { - var jointTransition = this.m_axis.x * dX + this.m_axis.y * dY; - if (b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2Settings.b2_linearSlop) { - this.m_limitState = b2Joint.e_equalLimits; - } - else if (jointTransition <= this.m_lowerTranslation) { - if (this.m_limitState != b2Joint.e_atLowerLimit) { - this.m_limitState = b2Joint.e_atLowerLimit; - this.m_impulse.y = 0.0; - } - } - else if (jointTransition >= this.m_upperTranslation) { - if (this.m_limitState != b2Joint.e_atUpperLimit) { - this.m_limitState = b2Joint.e_atUpperLimit; - this.m_impulse.y = 0.0; - } - } - else { - this.m_limitState = b2Joint.e_inactiveLimit; - this.m_impulse.y = 0.0; - } - } - else { - this.m_limitState = b2Joint.e_inactiveLimit; - } - if (this.m_enableMotor == false) { - this.m_motorImpulse = 0.0; - } - if (step.warmStarting) { - this.m_impulse.x *= step.dtRatio; - this.m_impulse.y *= step.dtRatio; - this.m_motorImpulse *= step.dtRatio; - var PX = this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.x; - var PY = this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.y) * this.m_axis.y; - var L1 = this.m_impulse.x * this.m_s1 + (this.m_motorImpulse + this.m_impulse.y) * this.m_a1; - var L2 = this.m_impulse.x * this.m_s2 + (this.m_motorImpulse + this.m_impulse.y) * this.m_a2; - bA.m_linearVelocity.x -= this.m_invMassA * PX; - bA.m_linearVelocity.y -= this.m_invMassA * PY; - bA.m_angularVelocity -= this.m_invIA * L1; - bB.m_linearVelocity.x += this.m_invMassB * PX; - bB.m_linearVelocity.y += this.m_invMassB * PY; - bB.m_angularVelocity += this.m_invIB * L2; - } - else { - this.m_impulse.SetZero(); - this.m_motorImpulse = 0.0; - } - } - b2LineJoint.prototype.SolveVelocityConstraints = function (step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var v1 = bA.m_linearVelocity; - var w1 = bA.m_angularVelocity; - var v2 = bB.m_linearVelocity; - var w2 = bB.m_angularVelocity; - var PX = 0; - var PY = 0; - var L1 = 0; - var L2 = 0; - if (this.m_enableMotor && this.m_limitState != b2Joint.e_equalLimits) { - var Cdot = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1; - var impulse = this.m_motorMass * (this.m_motorSpeed - Cdot); - var oldImpulse = this.m_motorImpulse; - var maxImpulse = step.dt * this.m_maxMotorForce; - this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, (-maxImpulse), maxImpulse); - impulse = this.m_motorImpulse - oldImpulse; - PX = impulse * this.m_axis.x; - PY = impulse * this.m_axis.y; - L1 = impulse * this.m_a1; - L2 = impulse * this.m_a2; - v1.x -= this.m_invMassA * PX; - v1.y -= this.m_invMassA * PY; - w1 -= this.m_invIA * L1; - v2.x += this.m_invMassB * PX; - v2.y += this.m_invMassB * PY; - w2 += this.m_invIB * L2; - } - var Cdot1 = this.m_perp.x * (v2.x - v1.x) + this.m_perp.y * (v2.y - v1.y) + this.m_s2 * w2 - this.m_s1 * w1; - if (this.m_enableLimit && this.m_limitState != b2Joint.e_inactiveLimit) { - var Cdot2 = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1; - var f1 = this.m_impulse.Copy(); - var df = this.m_K.Solve(new b2Vec2(), (-Cdot1), (-Cdot2)); - this.m_impulse.Add(df); - if (this.m_limitState == b2Joint.e_atLowerLimit) { - this.m_impulse.y = b2Math.Max(this.m_impulse.y, 0.0); - } - else if (this.m_limitState == b2Joint.e_atUpperLimit) { - this.m_impulse.y = b2Math.Min(this.m_impulse.y, 0.0); - } - var b = (-Cdot1) - (this.m_impulse.y - f1.y) * this.m_K.col2.x; - var f2r = 0; - if (this.m_K.col1.x != 0.0) { - f2r = b / this.m_K.col1.x + f1.x; - } - else { - f2r = f1.x; - } - this.m_impulse.x = f2r; - df.x = this.m_impulse.x - f1.x; - df.y = this.m_impulse.y - f1.y; - PX = df.x * this.m_perp.x + df.y * this.m_axis.x; - PY = df.x * this.m_perp.y + df.y * this.m_axis.y; - L1 = df.x * this.m_s1 + df.y * this.m_a1; - L2 = df.x * this.m_s2 + df.y * this.m_a2; - v1.x -= this.m_invMassA * PX; - v1.y -= this.m_invMassA * PY; - w1 -= this.m_invIA * L1; - v2.x += this.m_invMassB * PX; - v2.y += this.m_invMassB * PY; - w2 += this.m_invIB * L2; - } - else { - var df2 = 0; - if (this.m_K.col1.x != 0.0) { - df2 = ((-Cdot1)) / this.m_K.col1.x; - } - else { - df2 = 0.0; - } - this.m_impulse.x += df2; - PX = df2 * this.m_perp.x; - PY = df2 * this.m_perp.y; - L1 = df2 * this.m_s1; - L2 = df2 * this.m_s2; - v1.x -= this.m_invMassA * PX; - v1.y -= this.m_invMassA * PY; - w1 -= this.m_invIA * L1; - v2.x += this.m_invMassB * PX; - v2.y += this.m_invMassB * PY; - w2 += this.m_invIB * L2; - } - bA.m_linearVelocity.SetV(v1); - bA.m_angularVelocity = w1; - bB.m_linearVelocity.SetV(v2); - bB.m_angularVelocity = w2; - } - b2LineJoint.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - var limitC = 0; - var oldLimitImpulse = 0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var c1 = bA.m_sweep.c; - var a1 = bA.m_sweep.a; - var c2 = bB.m_sweep.c; - var a2 = bB.m_sweep.a; - var tMat; - var tX = 0; - var m1 = 0; - var m2 = 0; - var i1 = 0; - var i2 = 0; - var linearError = 0.0; - var angularError = 0.0; - var active = false; - var C2 = 0.0; - var R1 = b2Mat22.FromAngle(a1); - var R2 = b2Mat22.FromAngle(a2); - tMat = R1; - var r1X = this.m_localAnchor1.x - this.m_localCenterA.x; - var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = R2; - var r2X = this.m_localAnchor2.x - this.m_localCenterB.x; - var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var dX = c2.x + r2X - c1.x - r1X; - var dY = c2.y + r2Y - c1.y - r1Y; - if (this.m_enableLimit) { - this.m_axis = b2Math.MulMV(R1, this.m_localXAxis1); - this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x; - this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x; - var translation = this.m_axis.x * dX + this.m_axis.y * dY; - if (b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2Settings.b2_linearSlop) { - C2 = b2Math.Clamp(translation, (-b2Settings.b2_maxLinearCorrection), b2Settings.b2_maxLinearCorrection); - linearError = b2Math.Abs(translation); - active = true; - } - else if (translation <= this.m_lowerTranslation) { - C2 = b2Math.Clamp(translation - this.m_lowerTranslation + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0); - linearError = this.m_lowerTranslation - translation; - active = true; - } - else if (translation >= this.m_upperTranslation) { - C2 = b2Math.Clamp(translation - this.m_upperTranslation + b2Settings.b2_linearSlop, 0.0, b2Settings.b2_maxLinearCorrection); - linearError = translation - this.m_upperTranslation; - active = true; - } - } - this.m_perp = b2Math.MulMV(R1, this.m_localYAxis1); - this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x; - this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x; - var impulse = new b2Vec2(); - var C1 = this.m_perp.x * dX + this.m_perp.y * dY; - linearError = b2Math.Max(linearError, b2Math.Abs(C1)); - angularError = 0.0; - if (active) { - m1 = this.m_invMassA; - m2 = this.m_invMassB; - i1 = this.m_invIA; - i2 = this.m_invIB; - this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; - this.m_K.col1.y = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2; - this.m_K.col2.x = this.m_K.col1.y; - this.m_K.col2.y = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2; - this.m_K.Solve(impulse, (-C1), (-C2)); - } - else { - m1 = this.m_invMassA; - m2 = this.m_invMassB; - i1 = this.m_invIA; - i2 = this.m_invIB; - var k11 = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; - var impulse1 = 0; - if (k11 != 0.0) { - impulse1 = ((-C1)) / k11; - } - else { - impulse1 = 0.0; - } - impulse.x = impulse1; - impulse.y = 0.0; - } - var PX = impulse.x * this.m_perp.x + impulse.y * this.m_axis.x; - var PY = impulse.x * this.m_perp.y + impulse.y * this.m_axis.y; - var L1 = impulse.x * this.m_s1 + impulse.y * this.m_a1; - var L2 = impulse.x * this.m_s2 + impulse.y * this.m_a2; - c1.x -= this.m_invMassA * PX; - c1.y -= this.m_invMassA * PY; - a1 -= this.m_invIA * L1; - c2.x += this.m_invMassB * PX; - c2.y += this.m_invMassB * PY; - a2 += this.m_invIB * L2; - bA.m_sweep.a = a1; - bB.m_sweep.a = a2; - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - return linearError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop; - } - Box2D.inherit(b2LineJointDef, Box2D.Dynamics.Joints.b2JointDef); - b2LineJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; - b2LineJointDef.b2LineJointDef = function () { - Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); - this.localAnchorA = new b2Vec2(); - this.localAnchorB = new b2Vec2(); - this.localAxisA = new b2Vec2(); - }; - b2LineJointDef.prototype.b2LineJointDef = function () { - this.__super.b2JointDef.call(this); - this.type = b2Joint.e_lineJoint; - this.localAxisA.Set(1.0, 0.0); - this.enableLimit = false; - this.lowerTranslation = 0.0; - this.upperTranslation = 0.0; - this.enableMotor = false; - this.maxMotorForce = 0.0; - this.motorSpeed = 0.0; - } - b2LineJointDef.prototype.Initialize = function (bA, bB, anchor, axis) { - this.bodyA = bA; - this.bodyB = bB; - this.localAnchorA = this.bodyA.GetLocalPoint(anchor); - this.localAnchorB = this.bodyB.GetLocalPoint(anchor); - this.localAxisA = this.bodyA.GetLocalVector(axis); - } - Box2D.inherit(b2MouseJoint, Box2D.Dynamics.Joints.b2Joint); - b2MouseJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; - b2MouseJoint.b2MouseJoint = function () { - Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); - this.K = new b2Mat22(); - this.K1 = new b2Mat22(); - this.K2 = new b2Mat22(); - this.m_localAnchor = new b2Vec2(); - this.m_target = new b2Vec2(); - this.m_impulse = new b2Vec2(); - this.m_mass = new b2Mat22(); - this.m_C = new b2Vec2(); - }; - b2MouseJoint.prototype.GetAnchorA = function () { - return this.m_target; - } - b2MouseJoint.prototype.GetAnchorB = function () { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor); - } - b2MouseJoint.prototype.GetReactionForce = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y); - } - b2MouseJoint.prototype.GetReactionTorque = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return 0.0; - } - b2MouseJoint.prototype.GetTarget = function () { - return this.m_target; - } - b2MouseJoint.prototype.SetTarget = function (target) { - if (this.m_bodyB.IsAwake() == false) { - this.m_bodyB.SetAwake(true); - } - this.m_target = target; - } - b2MouseJoint.prototype.GetMaxForce = function () { - return this.m_maxForce; - } - b2MouseJoint.prototype.SetMaxForce = function (maxForce) { - if (maxForce === undefined) maxForce = 0; - this.m_maxForce = maxForce; - } - b2MouseJoint.prototype.GetFrequency = function () { - return this.m_frequencyHz; - } - b2MouseJoint.prototype.SetFrequency = function (hz) { - if (hz === undefined) hz = 0; - this.m_frequencyHz = hz; - } - b2MouseJoint.prototype.GetDampingRatio = function () { - return this.m_dampingRatio; - } - b2MouseJoint.prototype.SetDampingRatio = function (ratio) { - if (ratio === undefined) ratio = 0; - this.m_dampingRatio = ratio; - } - b2MouseJoint.prototype.b2MouseJoint = function (def) { - this.__super.b2Joint.call(this, def); - this.m_target.SetV(def.target); - var tX = this.m_target.x - this.m_bodyB.m_xf.position.x; - var tY = this.m_target.y - this.m_bodyB.m_xf.position.y; - var tMat = this.m_bodyB.m_xf.R; - this.m_localAnchor.x = (tX * tMat.col1.x + tY * tMat.col1.y); - this.m_localAnchor.y = (tX * tMat.col2.x + tY * tMat.col2.y); - this.m_maxForce = def.maxForce; - this.m_impulse.SetZero(); - this.m_frequencyHz = def.frequencyHz; - this.m_dampingRatio = def.dampingRatio; - this.m_beta = 0.0; - this.m_gamma = 0.0; - } - b2MouseJoint.prototype.InitVelocityConstraints = function (step) { - var b = this.m_bodyB; - var mass = b.GetMass(); - var omega = 2.0 * Math.PI * this.m_frequencyHz; - var d = 2.0 * mass * this.m_dampingRatio * omega; - var k = mass * omega * omega; - this.m_gamma = step.dt * (d + step.dt * k); - this.m_gamma = this.m_gamma != 0 ? 1 / this.m_gamma : 0.0; - this.m_beta = step.dt * k * this.m_gamma; - var tMat;tMat = b.m_xf.R; - var rX = this.m_localAnchor.x - b.m_sweep.localCenter.x; - var rY = this.m_localAnchor.y - b.m_sweep.localCenter.y; - var tX = (tMat.col1.x * rX + tMat.col2.x * rY);rY = (tMat.col1.y * rX + tMat.col2.y * rY); - rX = tX; - var invMass = b.m_invMass; - var invI = b.m_invI;this.K1.col1.x = invMass; - this.K1.col2.x = 0.0; - this.K1.col1.y = 0.0; - this.K1.col2.y = invMass; - this.K2.col1.x = invI * rY * rY; - this.K2.col2.x = (-invI * rX * rY); - this.K2.col1.y = (-invI * rX * rY); - this.K2.col2.y = invI * rX * rX; - this.K.SetM(this.K1); - this.K.AddM(this.K2); - this.K.col1.x += this.m_gamma; - this.K.col2.y += this.m_gamma; - this.K.GetInverse(this.m_mass); - this.m_C.x = b.m_sweep.c.x + rX - this.m_target.x; - this.m_C.y = b.m_sweep.c.y + rY - this.m_target.y; - b.m_angularVelocity *= 0.98; - this.m_impulse.x *= step.dtRatio; - this.m_impulse.y *= step.dtRatio; - b.m_linearVelocity.x += invMass * this.m_impulse.x; - b.m_linearVelocity.y += invMass * this.m_impulse.y; - b.m_angularVelocity += invI * (rX * this.m_impulse.y - rY * this.m_impulse.x); - } - b2MouseJoint.prototype.SolveVelocityConstraints = function (step) { - var b = this.m_bodyB; - var tMat; - var tX = 0; - var tY = 0; - tMat = b.m_xf.R; - var rX = this.m_localAnchor.x - b.m_sweep.localCenter.x; - var rY = this.m_localAnchor.y - b.m_sweep.localCenter.y; - tX = (tMat.col1.x * rX + tMat.col2.x * rY); - rY = (tMat.col1.y * rX + tMat.col2.y * rY); - rX = tX; - var CdotX = b.m_linearVelocity.x + ((-b.m_angularVelocity * rY)); - var CdotY = b.m_linearVelocity.y + (b.m_angularVelocity * rX); - tMat = this.m_mass; - tX = CdotX + this.m_beta * this.m_C.x + this.m_gamma * this.m_impulse.x; - tY = CdotY + this.m_beta * this.m_C.y + this.m_gamma * this.m_impulse.y; - var impulseX = (-(tMat.col1.x * tX + tMat.col2.x * tY)); - var impulseY = (-(tMat.col1.y * tX + tMat.col2.y * tY)); - var oldImpulseX = this.m_impulse.x; - var oldImpulseY = this.m_impulse.y; - this.m_impulse.x += impulseX; - this.m_impulse.y += impulseY; - var maxImpulse = step.dt * this.m_maxForce; - if (this.m_impulse.LengthSquared() > maxImpulse * maxImpulse) { - this.m_impulse.Multiply(maxImpulse / this.m_impulse.Length()); - } - impulseX = this.m_impulse.x - oldImpulseX; - impulseY = this.m_impulse.y - oldImpulseY; - b.m_linearVelocity.x += b.m_invMass * impulseX; - b.m_linearVelocity.y += b.m_invMass * impulseY; - b.m_angularVelocity += b.m_invI * (rX * impulseY - rY * impulseX); - } - b2MouseJoint.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - return true; - } - Box2D.inherit(b2MouseJointDef, Box2D.Dynamics.Joints.b2JointDef); - b2MouseJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; - b2MouseJointDef.b2MouseJointDef = function () { - Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); - this.target = new b2Vec2(); - }; - b2MouseJointDef.prototype.b2MouseJointDef = function () { - this.__super.b2JointDef.call(this); - this.type = b2Joint.e_mouseJoint; - this.maxForce = 0.0; - this.frequencyHz = 5.0; - this.dampingRatio = 0.7; - } - Box2D.inherit(b2PrismaticJoint, Box2D.Dynamics.Joints.b2Joint); - b2PrismaticJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; - b2PrismaticJoint.b2PrismaticJoint = function () { - Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); - this.m_localAnchor1 = new b2Vec2(); - this.m_localAnchor2 = new b2Vec2(); - this.m_localXAxis1 = new b2Vec2(); - this.m_localYAxis1 = new b2Vec2(); - this.m_axis = new b2Vec2(); - this.m_perp = new b2Vec2(); - this.m_K = new b2Mat33(); - this.m_impulse = new b2Vec3(); - }; - b2PrismaticJoint.prototype.GetAnchorA = function () { - return this.m_bodyA.GetWorldPoint(this.m_localAnchor1); - } - b2PrismaticJoint.prototype.GetAnchorB = function () { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor2); - } - b2PrismaticJoint.prototype.GetReactionForce = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return new b2Vec2(inv_dt * (this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.x), inv_dt * (this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.y)); - } - b2PrismaticJoint.prototype.GetReactionTorque = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return inv_dt * this.m_impulse.y; - } - b2PrismaticJoint.prototype.GetJointTranslation = function () { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var p1 = bA.GetWorldPoint(this.m_localAnchor1); - var p2 = bB.GetWorldPoint(this.m_localAnchor2); - var dX = p2.x - p1.x; - var dY = p2.y - p1.y; - var axis = bA.GetWorldVector(this.m_localXAxis1); - var translation = axis.x * dX + axis.y * dY; - return translation; - } - b2PrismaticJoint.prototype.GetJointSpeed = function () { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var p1X = bA.m_sweep.c.x + r1X; - var p1Y = bA.m_sweep.c.y + r1Y; - var p2X = bB.m_sweep.c.x + r2X; - var p2Y = bB.m_sweep.c.y + r2Y; - var dX = p2X - p1X; - var dY = p2Y - p1Y; - var axis = bA.GetWorldVector(this.m_localXAxis1); - var v1 = bA.m_linearVelocity; - var v2 = bB.m_linearVelocity; - var w1 = bA.m_angularVelocity; - var w2 = bB.m_angularVelocity; - var speed = (dX * ((-w1 * axis.y)) + dY * (w1 * axis.x)) + (axis.x * (((v2.x + ((-w2 * r2Y))) - v1.x) - ((-w1 * r1Y))) + axis.y * (((v2.y + (w2 * r2X)) - v1.y) - (w1 * r1X))); - return speed; - } - b2PrismaticJoint.prototype.IsLimitEnabled = function () { - return this.m_enableLimit; - } - b2PrismaticJoint.prototype.EnableLimit = function (flag) { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_enableLimit = flag; - } - b2PrismaticJoint.prototype.GetLowerLimit = function () { - return this.m_lowerTranslation; - } - b2PrismaticJoint.prototype.GetUpperLimit = function () { - return this.m_upperTranslation; - } - b2PrismaticJoint.prototype.SetLimits = function (lower, upper) { - if (lower === undefined) lower = 0; - if (upper === undefined) upper = 0; - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_lowerTranslation = lower; - this.m_upperTranslation = upper; - } - b2PrismaticJoint.prototype.IsMotorEnabled = function () { - return this.m_enableMotor; - } - b2PrismaticJoint.prototype.EnableMotor = function (flag) { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_enableMotor = flag; - } - b2PrismaticJoint.prototype.SetMotorSpeed = function (speed) { - if (speed === undefined) speed = 0; - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_motorSpeed = speed; - } - b2PrismaticJoint.prototype.GetMotorSpeed = function () { - return this.m_motorSpeed; - } - b2PrismaticJoint.prototype.SetMaxMotorForce = function (force) { - if (force === undefined) force = 0; - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_maxMotorForce = force; - } - b2PrismaticJoint.prototype.GetMotorForce = function () { - return this.m_motorImpulse; - } - b2PrismaticJoint.prototype.b2PrismaticJoint = function (def) { - this.__super.b2Joint.call(this, def); - var tMat; - var tX = 0; - var tY = 0; - this.m_localAnchor1.SetV(def.localAnchorA); - this.m_localAnchor2.SetV(def.localAnchorB); - this.m_localXAxis1.SetV(def.localAxisA); - this.m_localYAxis1.x = (-this.m_localXAxis1.y); - this.m_localYAxis1.y = this.m_localXAxis1.x; - this.m_refAngle = def.referenceAngle; - this.m_impulse.SetZero(); - this.m_motorMass = 0.0; - this.m_motorImpulse = 0.0; - this.m_lowerTranslation = def.lowerTranslation; - this.m_upperTranslation = def.upperTranslation; - this.m_maxMotorForce = def.maxMotorForce; - this.m_motorSpeed = def.motorSpeed; - this.m_enableLimit = def.enableLimit; - this.m_enableMotor = def.enableMotor; - this.m_limitState = b2Joint.e_inactiveLimit; - this.m_axis.SetZero(); - this.m_perp.SetZero(); - } - b2PrismaticJoint.prototype.InitVelocityConstraints = function (step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var tX = 0; - this.m_localCenterA.SetV(bA.GetLocalCenter()); - this.m_localCenterB.SetV(bB.GetLocalCenter()); - var xf1 = bA.GetTransform(); - var xf2 = bB.GetTransform(); - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - this.m_localCenterA.x; - var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - this.m_localCenterB.x; - var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var dX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; - var dY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; - this.m_invMassA = bA.m_invMass; - this.m_invMassB = bB.m_invMass; - this.m_invIA = bA.m_invI; - this.m_invIB = bB.m_invI; { - this.m_axis.SetV(b2Math.MulMV(xf1.R, this.m_localXAxis1)); - this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x; - this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x; - this.m_motorMass = this.m_invMassA + this.m_invMassB + this.m_invIA * this.m_a1 * this.m_a1 + this.m_invIB * this.m_a2 * this.m_a2; - if (this.m_motorMass > Number.MIN_VALUE) this.m_motorMass = 1.0 / this.m_motorMass; - } { - this.m_perp.SetV(b2Math.MulMV(xf1.R, this.m_localYAxis1)); - this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x; - this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x; - var m1 = this.m_invMassA; - var m2 = this.m_invMassB; - var i1 = this.m_invIA; - var i2 = this.m_invIB; - this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; - this.m_K.col1.y = i1 * this.m_s1 + i2 * this.m_s2; - this.m_K.col1.z = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2; - this.m_K.col2.x = this.m_K.col1.y; - this.m_K.col2.y = i1 + i2; - this.m_K.col2.z = i1 * this.m_a1 + i2 * this.m_a2; - this.m_K.col3.x = this.m_K.col1.z; - this.m_K.col3.y = this.m_K.col2.z; - this.m_K.col3.z = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2; - } - if (this.m_enableLimit) { - var jointTransition = this.m_axis.x * dX + this.m_axis.y * dY; - if (b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2Settings.b2_linearSlop) { - this.m_limitState = b2Joint.e_equalLimits; - } - else if (jointTransition <= this.m_lowerTranslation) { - if (this.m_limitState != b2Joint.e_atLowerLimit) { - this.m_limitState = b2Joint.e_atLowerLimit; - this.m_impulse.z = 0.0; - } - } - else if (jointTransition >= this.m_upperTranslation) { - if (this.m_limitState != b2Joint.e_atUpperLimit) { - this.m_limitState = b2Joint.e_atUpperLimit; - this.m_impulse.z = 0.0; - } - } - else { - this.m_limitState = b2Joint.e_inactiveLimit; - this.m_impulse.z = 0.0; - } - } - else { - this.m_limitState = b2Joint.e_inactiveLimit; - } - if (this.m_enableMotor == false) { - this.m_motorImpulse = 0.0; - } - if (step.warmStarting) { - this.m_impulse.x *= step.dtRatio; - this.m_impulse.y *= step.dtRatio; - this.m_motorImpulse *= step.dtRatio; - var PX = this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.x; - var PY = this.m_impulse.x * this.m_perp.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_axis.y; - var L1 = this.m_impulse.x * this.m_s1 + this.m_impulse.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_a1; - var L2 = this.m_impulse.x * this.m_s2 + this.m_impulse.y + (this.m_motorImpulse + this.m_impulse.z) * this.m_a2; - bA.m_linearVelocity.x -= this.m_invMassA * PX; - bA.m_linearVelocity.y -= this.m_invMassA * PY; - bA.m_angularVelocity -= this.m_invIA * L1; - bB.m_linearVelocity.x += this.m_invMassB * PX; - bB.m_linearVelocity.y += this.m_invMassB * PY; - bB.m_angularVelocity += this.m_invIB * L2; - } - else { - this.m_impulse.SetZero(); - this.m_motorImpulse = 0.0; - } - } - b2PrismaticJoint.prototype.SolveVelocityConstraints = function (step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var v1 = bA.m_linearVelocity; - var w1 = bA.m_angularVelocity; - var v2 = bB.m_linearVelocity; - var w2 = bB.m_angularVelocity; - var PX = 0; - var PY = 0; - var L1 = 0; - var L2 = 0; - if (this.m_enableMotor && this.m_limitState != b2Joint.e_equalLimits) { - var Cdot = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1; - var impulse = this.m_motorMass * (this.m_motorSpeed - Cdot); - var oldImpulse = this.m_motorImpulse; - var maxImpulse = step.dt * this.m_maxMotorForce; - this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, (-maxImpulse), maxImpulse); - impulse = this.m_motorImpulse - oldImpulse; - PX = impulse * this.m_axis.x; - PY = impulse * this.m_axis.y; - L1 = impulse * this.m_a1; - L2 = impulse * this.m_a2; - v1.x -= this.m_invMassA * PX; - v1.y -= this.m_invMassA * PY; - w1 -= this.m_invIA * L1; - v2.x += this.m_invMassB * PX; - v2.y += this.m_invMassB * PY; - w2 += this.m_invIB * L2; - } - var Cdot1X = this.m_perp.x * (v2.x - v1.x) + this.m_perp.y * (v2.y - v1.y) + this.m_s2 * w2 - this.m_s1 * w1; - var Cdot1Y = w2 - w1; - if (this.m_enableLimit && this.m_limitState != b2Joint.e_inactiveLimit) { - var Cdot2 = this.m_axis.x * (v2.x - v1.x) + this.m_axis.y * (v2.y - v1.y) + this.m_a2 * w2 - this.m_a1 * w1; - var f1 = this.m_impulse.Copy(); - var df = this.m_K.Solve33(new b2Vec3(), (-Cdot1X), (-Cdot1Y), (-Cdot2)); - this.m_impulse.Add(df); - if (this.m_limitState == b2Joint.e_atLowerLimit) { - this.m_impulse.z = b2Math.Max(this.m_impulse.z, 0.0); - } - else if (this.m_limitState == b2Joint.e_atUpperLimit) { - this.m_impulse.z = b2Math.Min(this.m_impulse.z, 0.0); - } - var bX = (-Cdot1X) - (this.m_impulse.z - f1.z) * this.m_K.col3.x; - var bY = (-Cdot1Y) - (this.m_impulse.z - f1.z) * this.m_K.col3.y; - var f2r = this.m_K.Solve22(new b2Vec2(), bX, bY); - f2r.x += f1.x; - f2r.y += f1.y; - this.m_impulse.x = f2r.x; - this.m_impulse.y = f2r.y; - df.x = this.m_impulse.x - f1.x; - df.y = this.m_impulse.y - f1.y; - df.z = this.m_impulse.z - f1.z; - PX = df.x * this.m_perp.x + df.z * this.m_axis.x; - PY = df.x * this.m_perp.y + df.z * this.m_axis.y; - L1 = df.x * this.m_s1 + df.y + df.z * this.m_a1; - L2 = df.x * this.m_s2 + df.y + df.z * this.m_a2; - v1.x -= this.m_invMassA * PX; - v1.y -= this.m_invMassA * PY; - w1 -= this.m_invIA * L1; - v2.x += this.m_invMassB * PX; - v2.y += this.m_invMassB * PY; - w2 += this.m_invIB * L2; - } - else { - var df2 = this.m_K.Solve22(new b2Vec2(), (-Cdot1X), (-Cdot1Y)); - this.m_impulse.x += df2.x; - this.m_impulse.y += df2.y; - PX = df2.x * this.m_perp.x; - PY = df2.x * this.m_perp.y; - L1 = df2.x * this.m_s1 + df2.y; - L2 = df2.x * this.m_s2 + df2.y; - v1.x -= this.m_invMassA * PX; - v1.y -= this.m_invMassA * PY; - w1 -= this.m_invIA * L1; - v2.x += this.m_invMassB * PX; - v2.y += this.m_invMassB * PY; - w2 += this.m_invIB * L2; - } - bA.m_linearVelocity.SetV(v1); - bA.m_angularVelocity = w1; - bB.m_linearVelocity.SetV(v2); - bB.m_angularVelocity = w2; - } - b2PrismaticJoint.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - var limitC = 0; - var oldLimitImpulse = 0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var c1 = bA.m_sweep.c; - var a1 = bA.m_sweep.a; - var c2 = bB.m_sweep.c; - var a2 = bB.m_sweep.a; - var tMat; - var tX = 0; - var m1 = 0; - var m2 = 0; - var i1 = 0; - var i2 = 0; - var linearError = 0.0; - var angularError = 0.0; - var active = false; - var C2 = 0.0; - var R1 = b2Mat22.FromAngle(a1); - var R2 = b2Mat22.FromAngle(a2); - tMat = R1; - var r1X = this.m_localAnchor1.x - this.m_localCenterA.x; - var r1Y = this.m_localAnchor1.y - this.m_localCenterA.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = R2; - var r2X = this.m_localAnchor2.x - this.m_localCenterB.x; - var r2Y = this.m_localAnchor2.y - this.m_localCenterB.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var dX = c2.x + r2X - c1.x - r1X; - var dY = c2.y + r2Y - c1.y - r1Y; - if (this.m_enableLimit) { - this.m_axis = b2Math.MulMV(R1, this.m_localXAxis1); - this.m_a1 = (dX + r1X) * this.m_axis.y - (dY + r1Y) * this.m_axis.x; - this.m_a2 = r2X * this.m_axis.y - r2Y * this.m_axis.x; - var translation = this.m_axis.x * dX + this.m_axis.y * dY; - if (b2Math.Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2Settings.b2_linearSlop) { - C2 = b2Math.Clamp(translation, (-b2Settings.b2_maxLinearCorrection), b2Settings.b2_maxLinearCorrection); - linearError = b2Math.Abs(translation); - active = true; - } - else if (translation <= this.m_lowerTranslation) { - C2 = b2Math.Clamp(translation - this.m_lowerTranslation + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0); - linearError = this.m_lowerTranslation - translation; - active = true; - } - else if (translation >= this.m_upperTranslation) { - C2 = b2Math.Clamp(translation - this.m_upperTranslation + b2Settings.b2_linearSlop, 0.0, b2Settings.b2_maxLinearCorrection); - linearError = translation - this.m_upperTranslation; - active = true; - } - } - this.m_perp = b2Math.MulMV(R1, this.m_localYAxis1); - this.m_s1 = (dX + r1X) * this.m_perp.y - (dY + r1Y) * this.m_perp.x; - this.m_s2 = r2X * this.m_perp.y - r2Y * this.m_perp.x; - var impulse = new b2Vec3(); - var C1X = this.m_perp.x * dX + this.m_perp.y * dY; - var C1Y = a2 - a1 - this.m_refAngle; - linearError = b2Math.Max(linearError, b2Math.Abs(C1X)); - angularError = b2Math.Abs(C1Y); - if (active) { - m1 = this.m_invMassA; - m2 = this.m_invMassB; - i1 = this.m_invIA; - i2 = this.m_invIB; - this.m_K.col1.x = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; - this.m_K.col1.y = i1 * this.m_s1 + i2 * this.m_s2; - this.m_K.col1.z = i1 * this.m_s1 * this.m_a1 + i2 * this.m_s2 * this.m_a2; - this.m_K.col2.x = this.m_K.col1.y; - this.m_K.col2.y = i1 + i2; - this.m_K.col2.z = i1 * this.m_a1 + i2 * this.m_a2; - this.m_K.col3.x = this.m_K.col1.z; - this.m_K.col3.y = this.m_K.col2.z; - this.m_K.col3.z = m1 + m2 + i1 * this.m_a1 * this.m_a1 + i2 * this.m_a2 * this.m_a2; - this.m_K.Solve33(impulse, (-C1X), (-C1Y), (-C2)); - } - else { - m1 = this.m_invMassA; - m2 = this.m_invMassB; - i1 = this.m_invIA; - i2 = this.m_invIB; - var k11 = m1 + m2 + i1 * this.m_s1 * this.m_s1 + i2 * this.m_s2 * this.m_s2; - var k12 = i1 * this.m_s1 + i2 * this.m_s2; - var k22 = i1 + i2; - this.m_K.col1.Set(k11, k12, 0.0); - this.m_K.col2.Set(k12, k22, 0.0); - var impulse1 = this.m_K.Solve22(new b2Vec2(), (-C1X), (-C1Y)); - impulse.x = impulse1.x; - impulse.y = impulse1.y; - impulse.z = 0.0; - } - var PX = impulse.x * this.m_perp.x + impulse.z * this.m_axis.x; - var PY = impulse.x * this.m_perp.y + impulse.z * this.m_axis.y; - var L1 = impulse.x * this.m_s1 + impulse.y + impulse.z * this.m_a1; - var L2 = impulse.x * this.m_s2 + impulse.y + impulse.z * this.m_a2; - c1.x -= this.m_invMassA * PX; - c1.y -= this.m_invMassA * PY; - a1 -= this.m_invIA * L1; - c2.x += this.m_invMassB * PX; - c2.y += this.m_invMassB * PY; - a2 += this.m_invIB * L2; - bA.m_sweep.a = a1; - bB.m_sweep.a = a2; - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - return linearError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop; - } - Box2D.inherit(b2PrismaticJointDef, Box2D.Dynamics.Joints.b2JointDef); - b2PrismaticJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; - b2PrismaticJointDef.b2PrismaticJointDef = function () { - Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); - this.localAnchorA = new b2Vec2(); - this.localAnchorB = new b2Vec2(); - this.localAxisA = new b2Vec2(); - }; - b2PrismaticJointDef.prototype.b2PrismaticJointDef = function () { - this.__super.b2JointDef.call(this); - this.type = b2Joint.e_prismaticJoint; - this.localAxisA.Set(1.0, 0.0); - this.referenceAngle = 0.0; - this.enableLimit = false; - this.lowerTranslation = 0.0; - this.upperTranslation = 0.0; - this.enableMotor = false; - this.maxMotorForce = 0.0; - this.motorSpeed = 0.0; - } - b2PrismaticJointDef.prototype.Initialize = function (bA, bB, anchor, axis) { - this.bodyA = bA; - this.bodyB = bB; - this.localAnchorA = this.bodyA.GetLocalPoint(anchor); - this.localAnchorB = this.bodyB.GetLocalPoint(anchor); - this.localAxisA = this.bodyA.GetLocalVector(axis); - this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle(); - } - Box2D.inherit(b2PulleyJoint, Box2D.Dynamics.Joints.b2Joint); - b2PulleyJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; - b2PulleyJoint.b2PulleyJoint = function () { - Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); - this.m_groundAnchor1 = new b2Vec2(); - this.m_groundAnchor2 = new b2Vec2(); - this.m_localAnchor1 = new b2Vec2(); - this.m_localAnchor2 = new b2Vec2(); - this.m_u1 = new b2Vec2(); - this.m_u2 = new b2Vec2(); - }; - b2PulleyJoint.prototype.GetAnchorA = function () { - return this.m_bodyA.GetWorldPoint(this.m_localAnchor1); - } - b2PulleyJoint.prototype.GetAnchorB = function () { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor2); - } - b2PulleyJoint.prototype.GetReactionForce = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return new b2Vec2(inv_dt * this.m_impulse * this.m_u2.x, inv_dt * this.m_impulse * this.m_u2.y); - } - b2PulleyJoint.prototype.GetReactionTorque = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return 0.0; - } - b2PulleyJoint.prototype.GetGroundAnchorA = function () { - var a = this.m_ground.m_xf.position.Copy(); - a.Add(this.m_groundAnchor1); - return a; - } - b2PulleyJoint.prototype.GetGroundAnchorB = function () { - var a = this.m_ground.m_xf.position.Copy(); - a.Add(this.m_groundAnchor2); - return a; - } - b2PulleyJoint.prototype.GetLength1 = function () { - var p = this.m_bodyA.GetWorldPoint(this.m_localAnchor1); - var sX = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x; - var sY = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y; - var dX = p.x - sX; - var dY = p.y - sY; - return Math.sqrt(dX * dX + dY * dY); - } - b2PulleyJoint.prototype.GetLength2 = function () { - var p = this.m_bodyB.GetWorldPoint(this.m_localAnchor2); - var sX = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x; - var sY = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y; - var dX = p.x - sX; - var dY = p.y - sY; - return Math.sqrt(dX * dX + dY * dY); - } - b2PulleyJoint.prototype.GetRatio = function () { - return this.m_ratio; - } - b2PulleyJoint.prototype.b2PulleyJoint = function (def) { - this.__super.b2Joint.call(this, def); - var tMat; - var tX = 0; - var tY = 0; - this.m_ground = this.m_bodyA.m_world.m_groundBody; - this.m_groundAnchor1.x = def.groundAnchorA.x - this.m_ground.m_xf.position.x; - this.m_groundAnchor1.y = def.groundAnchorA.y - this.m_ground.m_xf.position.y; - this.m_groundAnchor2.x = def.groundAnchorB.x - this.m_ground.m_xf.position.x; - this.m_groundAnchor2.y = def.groundAnchorB.y - this.m_ground.m_xf.position.y; - this.m_localAnchor1.SetV(def.localAnchorA); - this.m_localAnchor2.SetV(def.localAnchorB); - this.m_ratio = def.ratio; - this.m_constant = def.lengthA + this.m_ratio * def.lengthB; - this.m_maxLength1 = b2Math.Min(def.maxLengthA, this.m_constant - this.m_ratio * b2PulleyJoint.b2_minPulleyLength); - this.m_maxLength2 = b2Math.Min(def.maxLengthB, (this.m_constant - b2PulleyJoint.b2_minPulleyLength) / this.m_ratio); - this.m_impulse = 0.0; - this.m_limitImpulse1 = 0.0; - this.m_limitImpulse2 = 0.0; - } - b2PulleyJoint.prototype.InitVelocityConstraints = function (step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var p1X = bA.m_sweep.c.x + r1X; - var p1Y = bA.m_sweep.c.y + r1Y; - var p2X = bB.m_sweep.c.x + r2X; - var p2Y = bB.m_sweep.c.y + r2Y; - var s1X = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x; - var s1Y = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y; - var s2X = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x; - var s2Y = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y; - this.m_u1.Set(p1X - s1X, p1Y - s1Y); - this.m_u2.Set(p2X - s2X, p2Y - s2Y); - var length1 = this.m_u1.Length(); - var length2 = this.m_u2.Length(); - if (length1 > b2Settings.b2_linearSlop) { - this.m_u1.Multiply(1.0 / length1); - } - else { - this.m_u1.SetZero(); - } - if (length2 > b2Settings.b2_linearSlop) { - this.m_u2.Multiply(1.0 / length2); - } - else { - this.m_u2.SetZero(); - } - var C = this.m_constant - length1 - this.m_ratio * length2; - if (C > 0.0) { - this.m_state = b2Joint.e_inactiveLimit; - this.m_impulse = 0.0; - } - else { - this.m_state = b2Joint.e_atUpperLimit; - } - if (length1 < this.m_maxLength1) { - this.m_limitState1 = b2Joint.e_inactiveLimit; - this.m_limitImpulse1 = 0.0; - } - else { - this.m_limitState1 = b2Joint.e_atUpperLimit; - } - if (length2 < this.m_maxLength2) { - this.m_limitState2 = b2Joint.e_inactiveLimit; - this.m_limitImpulse2 = 0.0; - } - else { - this.m_limitState2 = b2Joint.e_atUpperLimit; - } - var cr1u1 = r1X * this.m_u1.y - r1Y * this.m_u1.x; - var cr2u2 = r2X * this.m_u2.y - r2Y * this.m_u2.x; - this.m_limitMass1 = bA.m_invMass + bA.m_invI * cr1u1 * cr1u1; - this.m_limitMass2 = bB.m_invMass + bB.m_invI * cr2u2 * cr2u2; - this.m_pulleyMass = this.m_limitMass1 + this.m_ratio * this.m_ratio * this.m_limitMass2; - this.m_limitMass1 = 1.0 / this.m_limitMass1; - this.m_limitMass2 = 1.0 / this.m_limitMass2; - this.m_pulleyMass = 1.0 / this.m_pulleyMass; - if (step.warmStarting) { - this.m_impulse *= step.dtRatio; - this.m_limitImpulse1 *= step.dtRatio; - this.m_limitImpulse2 *= step.dtRatio; - var P1X = ((-this.m_impulse) - this.m_limitImpulse1) * this.m_u1.x; - var P1Y = ((-this.m_impulse) - this.m_limitImpulse1) * this.m_u1.y; - var P2X = ((-this.m_ratio * this.m_impulse) - this.m_limitImpulse2) * this.m_u2.x; - var P2Y = ((-this.m_ratio * this.m_impulse) - this.m_limitImpulse2) * this.m_u2.y; - bA.m_linearVelocity.x += bA.m_invMass * P1X; - bA.m_linearVelocity.y += bA.m_invMass * P1Y; - bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X); - bB.m_linearVelocity.x += bB.m_invMass * P2X; - bB.m_linearVelocity.y += bB.m_invMass * P2Y; - bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X); - } - else { - this.m_impulse = 0.0; - this.m_limitImpulse1 = 0.0; - this.m_limitImpulse2 = 0.0; - } - } - b2PulleyJoint.prototype.SolveVelocityConstraints = function (step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - var tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var v1X = 0; - var v1Y = 0; - var v2X = 0; - var v2Y = 0; - var P1X = 0; - var P1Y = 0; - var P2X = 0; - var P2Y = 0; - var Cdot = 0; - var impulse = 0; - var oldImpulse = 0; - if (this.m_state == b2Joint.e_atUpperLimit) { - v1X = bA.m_linearVelocity.x + ((-bA.m_angularVelocity * r1Y)); - v1Y = bA.m_linearVelocity.y + (bA.m_angularVelocity * r1X); - v2X = bB.m_linearVelocity.x + ((-bB.m_angularVelocity * r2Y)); - v2Y = bB.m_linearVelocity.y + (bB.m_angularVelocity * r2X); - Cdot = (-(this.m_u1.x * v1X + this.m_u1.y * v1Y)) - this.m_ratio * (this.m_u2.x * v2X + this.m_u2.y * v2Y); - impulse = this.m_pulleyMass * ((-Cdot)); - oldImpulse = this.m_impulse; - this.m_impulse = b2Math.Max(0.0, this.m_impulse + impulse); - impulse = this.m_impulse - oldImpulse; - P1X = (-impulse * this.m_u1.x); - P1Y = (-impulse * this.m_u1.y); - P2X = (-this.m_ratio * impulse * this.m_u2.x); - P2Y = (-this.m_ratio * impulse * this.m_u2.y); - bA.m_linearVelocity.x += bA.m_invMass * P1X; - bA.m_linearVelocity.y += bA.m_invMass * P1Y; - bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X); - bB.m_linearVelocity.x += bB.m_invMass * P2X; - bB.m_linearVelocity.y += bB.m_invMass * P2Y; - bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X); - } - if (this.m_limitState1 == b2Joint.e_atUpperLimit) { - v1X = bA.m_linearVelocity.x + ((-bA.m_angularVelocity * r1Y)); - v1Y = bA.m_linearVelocity.y + (bA.m_angularVelocity * r1X); - Cdot = (-(this.m_u1.x * v1X + this.m_u1.y * v1Y)); - impulse = (-this.m_limitMass1 * Cdot); - oldImpulse = this.m_limitImpulse1; - this.m_limitImpulse1 = b2Math.Max(0.0, this.m_limitImpulse1 + impulse); - impulse = this.m_limitImpulse1 - oldImpulse; - P1X = (-impulse * this.m_u1.x); - P1Y = (-impulse * this.m_u1.y); - bA.m_linearVelocity.x += bA.m_invMass * P1X; - bA.m_linearVelocity.y += bA.m_invMass * P1Y; - bA.m_angularVelocity += bA.m_invI * (r1X * P1Y - r1Y * P1X); - } - if (this.m_limitState2 == b2Joint.e_atUpperLimit) { - v2X = bB.m_linearVelocity.x + ((-bB.m_angularVelocity * r2Y)); - v2Y = bB.m_linearVelocity.y + (bB.m_angularVelocity * r2X); - Cdot = (-(this.m_u2.x * v2X + this.m_u2.y * v2Y)); - impulse = (-this.m_limitMass2 * Cdot); - oldImpulse = this.m_limitImpulse2; - this.m_limitImpulse2 = b2Math.Max(0.0, this.m_limitImpulse2 + impulse); - impulse = this.m_limitImpulse2 - oldImpulse; - P2X = (-impulse * this.m_u2.x); - P2Y = (-impulse * this.m_u2.y); - bB.m_linearVelocity.x += bB.m_invMass * P2X; - bB.m_linearVelocity.y += bB.m_invMass * P2Y; - bB.m_angularVelocity += bB.m_invI * (r2X * P2Y - r2Y * P2X); - } - } - b2PulleyJoint.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var s1X = this.m_ground.m_xf.position.x + this.m_groundAnchor1.x; - var s1Y = this.m_ground.m_xf.position.y + this.m_groundAnchor1.y; - var s2X = this.m_ground.m_xf.position.x + this.m_groundAnchor2.x; - var s2Y = this.m_ground.m_xf.position.y + this.m_groundAnchor2.y; - var r1X = 0; - var r1Y = 0; - var r2X = 0; - var r2Y = 0; - var p1X = 0; - var p1Y = 0; - var p2X = 0; - var p2Y = 0; - var length1 = 0; - var length2 = 0; - var C = 0; - var impulse = 0; - var oldImpulse = 0; - var oldLimitPositionImpulse = 0; - var tX = 0; - var linearError = 0.0; - if (this.m_state == b2Joint.e_atUpperLimit) { - tMat = bA.m_xf.R; - r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - p1X = bA.m_sweep.c.x + r1X; - p1Y = bA.m_sweep.c.y + r1Y; - p2X = bB.m_sweep.c.x + r2X; - p2Y = bB.m_sweep.c.y + r2Y; - this.m_u1.Set(p1X - s1X, p1Y - s1Y); - this.m_u2.Set(p2X - s2X, p2Y - s2Y); - length1 = this.m_u1.Length(); - length2 = this.m_u2.Length(); - if (length1 > b2Settings.b2_linearSlop) { - this.m_u1.Multiply(1.0 / length1); - } - else { - this.m_u1.SetZero(); - } - if (length2 > b2Settings.b2_linearSlop) { - this.m_u2.Multiply(1.0 / length2); - } - else { - this.m_u2.SetZero(); - } - C = this.m_constant - length1 - this.m_ratio * length2; - linearError = b2Math.Max(linearError, (-C)); - C = b2Math.Clamp(C + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0); - impulse = (-this.m_pulleyMass * C); - p1X = (-impulse * this.m_u1.x); - p1Y = (-impulse * this.m_u1.y); - p2X = (-this.m_ratio * impulse * this.m_u2.x); - p2Y = (-this.m_ratio * impulse * this.m_u2.y); - bA.m_sweep.c.x += bA.m_invMass * p1X; - bA.m_sweep.c.y += bA.m_invMass * p1Y; - bA.m_sweep.a += bA.m_invI * (r1X * p1Y - r1Y * p1X); - bB.m_sweep.c.x += bB.m_invMass * p2X; - bB.m_sweep.c.y += bB.m_invMass * p2Y; - bB.m_sweep.a += bB.m_invI * (r2X * p2Y - r2Y * p2X); - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - } - if (this.m_limitState1 == b2Joint.e_atUpperLimit) { - tMat = bA.m_xf.R; - r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - p1X = bA.m_sweep.c.x + r1X; - p1Y = bA.m_sweep.c.y + r1Y; - this.m_u1.Set(p1X - s1X, p1Y - s1Y); - length1 = this.m_u1.Length(); - if (length1 > b2Settings.b2_linearSlop) { - this.m_u1.x *= 1.0 / length1; - this.m_u1.y *= 1.0 / length1; - } - else { - this.m_u1.SetZero(); - } - C = this.m_maxLength1 - length1; - linearError = b2Math.Max(linearError, (-C)); - C = b2Math.Clamp(C + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0); - impulse = (-this.m_limitMass1 * C); - p1X = (-impulse * this.m_u1.x); - p1Y = (-impulse * this.m_u1.y); - bA.m_sweep.c.x += bA.m_invMass * p1X; - bA.m_sweep.c.y += bA.m_invMass * p1Y; - bA.m_sweep.a += bA.m_invI * (r1X * p1Y - r1Y * p1X); - bA.SynchronizeTransform(); - } - if (this.m_limitState2 == b2Joint.e_atUpperLimit) { - tMat = bB.m_xf.R; - r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - p2X = bB.m_sweep.c.x + r2X; - p2Y = bB.m_sweep.c.y + r2Y; - this.m_u2.Set(p2X - s2X, p2Y - s2Y); - length2 = this.m_u2.Length(); - if (length2 > b2Settings.b2_linearSlop) { - this.m_u2.x *= 1.0 / length2; - this.m_u2.y *= 1.0 / length2; - } - else { - this.m_u2.SetZero(); - } - C = this.m_maxLength2 - length2; - linearError = b2Math.Max(linearError, (-C)); - C = b2Math.Clamp(C + b2Settings.b2_linearSlop, (-b2Settings.b2_maxLinearCorrection), 0.0); - impulse = (-this.m_limitMass2 * C); - p2X = (-impulse * this.m_u2.x); - p2Y = (-impulse * this.m_u2.y); - bB.m_sweep.c.x += bB.m_invMass * p2X; - bB.m_sweep.c.y += bB.m_invMass * p2Y; - bB.m_sweep.a += bB.m_invI * (r2X * p2Y - r2Y * p2X); - bB.SynchronizeTransform(); - } - return linearError < b2Settings.b2_linearSlop; - } - Box2D.postDefs.push(function () { - Box2D.Dynamics.Joints.b2PulleyJoint.b2_minPulleyLength = 2.0; - }); - Box2D.inherit(b2PulleyJointDef, Box2D.Dynamics.Joints.b2JointDef); - b2PulleyJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; - b2PulleyJointDef.b2PulleyJointDef = function () { - Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); - this.groundAnchorA = new b2Vec2(); - this.groundAnchorB = new b2Vec2(); - this.localAnchorA = new b2Vec2(); - this.localAnchorB = new b2Vec2(); - }; - b2PulleyJointDef.prototype.b2PulleyJointDef = function () { - this.__super.b2JointDef.call(this); - this.type = b2Joint.e_pulleyJoint; - this.groundAnchorA.Set((-1.0), 1.0); - this.groundAnchorB.Set(1.0, 1.0); - this.localAnchorA.Set((-1.0), 0.0); - this.localAnchorB.Set(1.0, 0.0); - this.lengthA = 0.0; - this.maxLengthA = 0.0; - this.lengthB = 0.0; - this.maxLengthB = 0.0; - this.ratio = 1.0; - this.collideConnected = true; - } - b2PulleyJointDef.prototype.Initialize = function (bA, bB, gaA, gaB, anchorA, anchorB, r) { - if (r === undefined) r = 0; - this.bodyA = bA; - this.bodyB = bB; - this.groundAnchorA.SetV(gaA); - this.groundAnchorB.SetV(gaB); - this.localAnchorA = this.bodyA.GetLocalPoint(anchorA); - this.localAnchorB = this.bodyB.GetLocalPoint(anchorB); - var d1X = anchorA.x - gaA.x; - var d1Y = anchorA.y - gaA.y; - this.lengthA = Math.sqrt(d1X * d1X + d1Y * d1Y); - var d2X = anchorB.x - gaB.x; - var d2Y = anchorB.y - gaB.y; - this.lengthB = Math.sqrt(d2X * d2X + d2Y * d2Y); - this.ratio = r; - var C = this.lengthA + this.ratio * this.lengthB; - this.maxLengthA = C - this.ratio * b2PulleyJoint.b2_minPulleyLength; - this.maxLengthB = (C - b2PulleyJoint.b2_minPulleyLength) / this.ratio; - } - Box2D.inherit(b2RevoluteJoint, Box2D.Dynamics.Joints.b2Joint); - b2RevoluteJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; - b2RevoluteJoint.b2RevoluteJoint = function () { - Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); - this.K = new b2Mat22(); - this.K1 = new b2Mat22(); - this.K2 = new b2Mat22(); - this.K3 = new b2Mat22(); - this.impulse3 = new b2Vec3(); - this.impulse2 = new b2Vec2(); - this.reduced = new b2Vec2(); - this.m_localAnchor1 = new b2Vec2(); - this.m_localAnchor2 = new b2Vec2(); - this.m_impulse = new b2Vec3(); - this.m_mass = new b2Mat33(); - }; - b2RevoluteJoint.prototype.GetAnchorA = function () { - return this.m_bodyA.GetWorldPoint(this.m_localAnchor1); - } - b2RevoluteJoint.prototype.GetAnchorB = function () { - return this.m_bodyB.GetWorldPoint(this.m_localAnchor2); - } - b2RevoluteJoint.prototype.GetReactionForce = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y); - } - b2RevoluteJoint.prototype.GetReactionTorque = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return inv_dt * this.m_impulse.z; - } - b2RevoluteJoint.prototype.GetJointAngle = function () { - return this.m_bodyB.m_sweep.a - this.m_bodyA.m_sweep.a - this.m_referenceAngle; - } - b2RevoluteJoint.prototype.GetJointSpeed = function () { - return this.m_bodyB.m_angularVelocity - this.m_bodyA.m_angularVelocity; - } - b2RevoluteJoint.prototype.IsLimitEnabled = function () { - return this.m_enableLimit; - } - b2RevoluteJoint.prototype.EnableLimit = function (flag) { - this.m_enableLimit = flag; - } - b2RevoluteJoint.prototype.GetLowerLimit = function () { - return this.m_lowerAngle; - } - b2RevoluteJoint.prototype.GetUpperLimit = function () { - return this.m_upperAngle; - } - b2RevoluteJoint.prototype.SetLimits = function (lower, upper) { - if (lower === undefined) lower = 0; - if (upper === undefined) upper = 0; - this.m_lowerAngle = lower; - this.m_upperAngle = upper; - } - b2RevoluteJoint.prototype.IsMotorEnabled = function () { - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - return this.m_enableMotor; - } - b2RevoluteJoint.prototype.EnableMotor = function (flag) { - this.m_enableMotor = flag; - } - b2RevoluteJoint.prototype.SetMotorSpeed = function (speed) { - if (speed === undefined) speed = 0; - this.m_bodyA.SetAwake(true); - this.m_bodyB.SetAwake(true); - this.m_motorSpeed = speed; - } - b2RevoluteJoint.prototype.GetMotorSpeed = function () { - return this.m_motorSpeed; - } - b2RevoluteJoint.prototype.SetMaxMotorTorque = function (torque) { - if (torque === undefined) torque = 0; - this.m_maxMotorTorque = torque; - } - b2RevoluteJoint.prototype.GetMotorTorque = function () { - return this.m_maxMotorTorque; - } - b2RevoluteJoint.prototype.b2RevoluteJoint = function (def) { - this.__super.b2Joint.call(this, def); - this.m_localAnchor1.SetV(def.localAnchorA); - this.m_localAnchor2.SetV(def.localAnchorB); - this.m_referenceAngle = def.referenceAngle; - this.m_impulse.SetZero(); - this.m_motorImpulse = 0.0; - this.m_lowerAngle = def.lowerAngle; - this.m_upperAngle = def.upperAngle; - this.m_maxMotorTorque = def.maxMotorTorque; - this.m_motorSpeed = def.motorSpeed; - this.m_enableLimit = def.enableLimit; - this.m_enableMotor = def.enableMotor; - this.m_limitState = b2Joint.e_inactiveLimit; - } - b2RevoluteJoint.prototype.InitVelocityConstraints = function (step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var tX = 0; - if (this.m_enableMotor || this.m_enableLimit) {} - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var m1 = bA.m_invMass; - var m2 = bB.m_invMass; - var i1 = bA.m_invI; - var i2 = bB.m_invI; - this.m_mass.col1.x = m1 + m2 + r1Y * r1Y * i1 + r2Y * r2Y * i2; - this.m_mass.col2.x = (-r1Y * r1X * i1) - r2Y * r2X * i2; - this.m_mass.col3.x = (-r1Y * i1) - r2Y * i2; - this.m_mass.col1.y = this.m_mass.col2.x; - this.m_mass.col2.y = m1 + m2 + r1X * r1X * i1 + r2X * r2X * i2; - this.m_mass.col3.y = r1X * i1 + r2X * i2; - this.m_mass.col1.z = this.m_mass.col3.x; - this.m_mass.col2.z = this.m_mass.col3.y; - this.m_mass.col3.z = i1 + i2; - this.m_motorMass = 1.0 / (i1 + i2); - if (this.m_enableMotor == false) { - this.m_motorImpulse = 0.0; - } - if (this.m_enableLimit) { - var jointAngle = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle; - if (b2Math.Abs(this.m_upperAngle - this.m_lowerAngle) < 2.0 * b2Settings.b2_angularSlop) { - this.m_limitState = b2Joint.e_equalLimits; - } - else if (jointAngle <= this.m_lowerAngle) { - if (this.m_limitState != b2Joint.e_atLowerLimit) { - this.m_impulse.z = 0.0; - } - this.m_limitState = b2Joint.e_atLowerLimit; - } - else if (jointAngle >= this.m_upperAngle) { - if (this.m_limitState != b2Joint.e_atUpperLimit) { - this.m_impulse.z = 0.0; - } - this.m_limitState = b2Joint.e_atUpperLimit; - } - else { - this.m_limitState = b2Joint.e_inactiveLimit; - this.m_impulse.z = 0.0; - } - } - else { - this.m_limitState = b2Joint.e_inactiveLimit; - } - if (step.warmStarting) { - this.m_impulse.x *= step.dtRatio; - this.m_impulse.y *= step.dtRatio; - this.m_motorImpulse *= step.dtRatio; - var PX = this.m_impulse.x; - var PY = this.m_impulse.y; - bA.m_linearVelocity.x -= m1 * PX; - bA.m_linearVelocity.y -= m1 * PY; - bA.m_angularVelocity -= i1 * ((r1X * PY - r1Y * PX) + this.m_motorImpulse + this.m_impulse.z); - bB.m_linearVelocity.x += m2 * PX; - bB.m_linearVelocity.y += m2 * PY; - bB.m_angularVelocity += i2 * ((r2X * PY - r2Y * PX) + this.m_motorImpulse + this.m_impulse.z); - } - else { - this.m_impulse.SetZero(); - this.m_motorImpulse = 0.0; - } - } - b2RevoluteJoint.prototype.SolveVelocityConstraints = function (step) { - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var tMat; - var tX = 0; - var newImpulse = 0; - var r1X = 0; - var r1Y = 0; - var r2X = 0; - var r2Y = 0; - var v1 = bA.m_linearVelocity; - var w1 = bA.m_angularVelocity; - var v2 = bB.m_linearVelocity; - var w2 = bB.m_angularVelocity; - var m1 = bA.m_invMass; - var m2 = bB.m_invMass; - var i1 = bA.m_invI; - var i2 = bB.m_invI; - if (this.m_enableMotor && this.m_limitState != b2Joint.e_equalLimits) { - var Cdot = w2 - w1 - this.m_motorSpeed; - var impulse = this.m_motorMass * ((-Cdot)); - var oldImpulse = this.m_motorImpulse; - var maxImpulse = step.dt * this.m_maxMotorTorque; - this.m_motorImpulse = b2Math.Clamp(this.m_motorImpulse + impulse, (-maxImpulse), maxImpulse); - impulse = this.m_motorImpulse - oldImpulse; - w1 -= i1 * impulse; - w2 += i2 * impulse; - } - if (this.m_enableLimit && this.m_limitState != b2Joint.e_inactiveLimit) { - tMat = bA.m_xf.R; - r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var Cdot1X = v2.x + ((-w2 * r2Y)) - v1.x - ((-w1 * r1Y)); - var Cdot1Y = v2.y + (w2 * r2X) - v1.y - (w1 * r1X); - var Cdot2 = w2 - w1; - this.m_mass.Solve33(this.impulse3, (-Cdot1X), (-Cdot1Y), (-Cdot2)); - if (this.m_limitState == b2Joint.e_equalLimits) { - this.m_impulse.Add(this.impulse3); - } - else if (this.m_limitState == b2Joint.e_atLowerLimit) { - newImpulse = this.m_impulse.z + this.impulse3.z; - if (newImpulse < 0.0) { - this.m_mass.Solve22(this.reduced, (-Cdot1X), (-Cdot1Y)); - this.impulse3.x = this.reduced.x; - this.impulse3.y = this.reduced.y; - this.impulse3.z = (-this.m_impulse.z); - this.m_impulse.x += this.reduced.x; - this.m_impulse.y += this.reduced.y; - this.m_impulse.z = 0.0; - } - } - else if (this.m_limitState == b2Joint.e_atUpperLimit) { - newImpulse = this.m_impulse.z + this.impulse3.z; - if (newImpulse > 0.0) { - this.m_mass.Solve22(this.reduced, (-Cdot1X), (-Cdot1Y)); - this.impulse3.x = this.reduced.x; - this.impulse3.y = this.reduced.y; - this.impulse3.z = (-this.m_impulse.z); - this.m_impulse.x += this.reduced.x; - this.m_impulse.y += this.reduced.y; - this.m_impulse.z = 0.0; - } - } - v1.x -= m1 * this.impulse3.x; - v1.y -= m1 * this.impulse3.y; - w1 -= i1 * (r1X * this.impulse3.y - r1Y * this.impulse3.x + this.impulse3.z); - v2.x += m2 * this.impulse3.x; - v2.y += m2 * this.impulse3.y; - w2 += i2 * (r2X * this.impulse3.y - r2Y * this.impulse3.x + this.impulse3.z); - } - else { - tMat = bA.m_xf.R; - r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var CdotX = v2.x + ((-w2 * r2Y)) - v1.x - ((-w1 * r1Y)); - var CdotY = v2.y + (w2 * r2X) - v1.y - (w1 * r1X); - this.m_mass.Solve22(this.impulse2, (-CdotX), (-CdotY)); - this.m_impulse.x += this.impulse2.x; - this.m_impulse.y += this.impulse2.y; - v1.x -= m1 * this.impulse2.x; - v1.y -= m1 * this.impulse2.y; - w1 -= i1 * (r1X * this.impulse2.y - r1Y * this.impulse2.x); - v2.x += m2 * this.impulse2.x; - v2.y += m2 * this.impulse2.y; - w2 += i2 * (r2X * this.impulse2.y - r2Y * this.impulse2.x); - } - bA.m_linearVelocity.SetV(v1); - bA.m_angularVelocity = w1; - bB.m_linearVelocity.SetV(v2); - bB.m_angularVelocity = w2; - } - b2RevoluteJoint.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - var oldLimitImpulse = 0; - var C = 0; - var tMat; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var angularError = 0.0; - var positionError = 0.0; - var tX = 0; - var impulseX = 0; - var impulseY = 0; - if (this.m_enableLimit && this.m_limitState != b2Joint.e_inactiveLimit) { - var angle = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle; - var limitImpulse = 0.0; - if (this.m_limitState == b2Joint.e_equalLimits) { - C = b2Math.Clamp(angle - this.m_lowerAngle, (-b2Settings.b2_maxAngularCorrection), b2Settings.b2_maxAngularCorrection); - limitImpulse = (-this.m_motorMass * C); - angularError = b2Math.Abs(C); - } - else if (this.m_limitState == b2Joint.e_atLowerLimit) { - C = angle - this.m_lowerAngle; - angularError = (-C); - C = b2Math.Clamp(C + b2Settings.b2_angularSlop, (-b2Settings.b2_maxAngularCorrection), 0.0); - limitImpulse = (-this.m_motorMass * C); - } - else if (this.m_limitState == b2Joint.e_atUpperLimit) { - C = angle - this.m_upperAngle; - angularError = C; - C = b2Math.Clamp(C - b2Settings.b2_angularSlop, 0.0, b2Settings.b2_maxAngularCorrection); - limitImpulse = (-this.m_motorMass * C); - } - bA.m_sweep.a -= bA.m_invI * limitImpulse; - bB.m_sweep.a += bB.m_invI * limitImpulse; - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - } { - tMat = bA.m_xf.R; - var r1X = this.m_localAnchor1.x - bA.m_sweep.localCenter.x; - var r1Y = this.m_localAnchor1.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * r1X + tMat.col2.x * r1Y); - r1Y = (tMat.col1.y * r1X + tMat.col2.y * r1Y); - r1X = tX; - tMat = bB.m_xf.R; - var r2X = this.m_localAnchor2.x - bB.m_sweep.localCenter.x; - var r2Y = this.m_localAnchor2.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * r2X + tMat.col2.x * r2Y); - r2Y = (tMat.col1.y * r2X + tMat.col2.y * r2Y); - r2X = tX; - var CX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; - var CY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; - var CLengthSquared = CX * CX + CY * CY; - var CLength = Math.sqrt(CLengthSquared); - positionError = CLength; - var invMass1 = bA.m_invMass; - var invMass2 = bB.m_invMass; - var invI1 = bA.m_invI; - var invI2 = bB.m_invI; - var k_allowedStretch = 10.0 * b2Settings.b2_linearSlop; - if (CLengthSquared > k_allowedStretch * k_allowedStretch) { - var uX = CX / CLength; - var uY = CY / CLength; - var k = invMass1 + invMass2; - var m = 1.0 / k; - impulseX = m * ((-CX)); - impulseY = m * ((-CY)); - var k_beta = 0.5; - bA.m_sweep.c.x -= k_beta * invMass1 * impulseX; - bA.m_sweep.c.y -= k_beta * invMass1 * impulseY; - bB.m_sweep.c.x += k_beta * invMass2 * impulseX; - bB.m_sweep.c.y += k_beta * invMass2 * impulseY; - CX = bB.m_sweep.c.x + r2X - bA.m_sweep.c.x - r1X; - CY = bB.m_sweep.c.y + r2Y - bA.m_sweep.c.y - r1Y; - } - this.K1.col1.x = invMass1 + invMass2; - this.K1.col2.x = 0.0; - this.K1.col1.y = 0.0; - this.K1.col2.y = invMass1 + invMass2; - this.K2.col1.x = invI1 * r1Y * r1Y; - this.K2.col2.x = (-invI1 * r1X * r1Y); - this.K2.col1.y = (-invI1 * r1X * r1Y); - this.K2.col2.y = invI1 * r1X * r1X; - this.K3.col1.x = invI2 * r2Y * r2Y; - this.K3.col2.x = (-invI2 * r2X * r2Y); - this.K3.col1.y = (-invI2 * r2X * r2Y); - this.K3.col2.y = invI2 * r2X * r2X; - this.K.SetM(this.K1); - this.K.AddM(this.K2); - this.K.AddM(this.K3); - this.K.Solve(b2RevoluteJoint.tImpulse, (-CX), (-CY)); - impulseX = b2RevoluteJoint.tImpulse.x; - impulseY = b2RevoluteJoint.tImpulse.y; - bA.m_sweep.c.x -= bA.m_invMass * impulseX; - bA.m_sweep.c.y -= bA.m_invMass * impulseY; - bA.m_sweep.a -= bA.m_invI * (r1X * impulseY - r1Y * impulseX); - bB.m_sweep.c.x += bB.m_invMass * impulseX; - bB.m_sweep.c.y += bB.m_invMass * impulseY; - bB.m_sweep.a += bB.m_invI * (r2X * impulseY - r2Y * impulseX); - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - } - return positionError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop; - } - Box2D.postDefs.push(function () { - Box2D.Dynamics.Joints.b2RevoluteJoint.tImpulse = new b2Vec2(); - }); - Box2D.inherit(b2RevoluteJointDef, Box2D.Dynamics.Joints.b2JointDef); - b2RevoluteJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; - b2RevoluteJointDef.b2RevoluteJointDef = function () { - Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); - this.localAnchorA = new b2Vec2(); - this.localAnchorB = new b2Vec2(); - }; - b2RevoluteJointDef.prototype.b2RevoluteJointDef = function () { - this.__super.b2JointDef.call(this); - this.type = b2Joint.e_revoluteJoint; - this.localAnchorA.Set(0.0, 0.0); - this.localAnchorB.Set(0.0, 0.0); - this.referenceAngle = 0.0; - this.lowerAngle = 0.0; - this.upperAngle = 0.0; - this.maxMotorTorque = 0.0; - this.motorSpeed = 0.0; - this.enableLimit = false; - this.enableMotor = false; - } - b2RevoluteJointDef.prototype.Initialize = function (bA, bB, anchor) { - this.bodyA = bA; - this.bodyB = bB; - this.localAnchorA = this.bodyA.GetLocalPoint(anchor); - this.localAnchorB = this.bodyB.GetLocalPoint(anchor); - this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle(); - } - Box2D.inherit(b2WeldJoint, Box2D.Dynamics.Joints.b2Joint); - b2WeldJoint.prototype.__super = Box2D.Dynamics.Joints.b2Joint.prototype; - b2WeldJoint.b2WeldJoint = function () { - Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this, arguments); - this.m_localAnchorA = new b2Vec2(); - this.m_localAnchorB = new b2Vec2(); - this.m_impulse = new b2Vec3(); - this.m_mass = new b2Mat33(); - }; - b2WeldJoint.prototype.GetAnchorA = function () { - return this.m_bodyA.GetWorldPoint(this.m_localAnchorA); - } - b2WeldJoint.prototype.GetAnchorB = function () { - return this.m_bodyB.GetWorldPoint(this.m_localAnchorB); - } - b2WeldJoint.prototype.GetReactionForce = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return new b2Vec2(inv_dt * this.m_impulse.x, inv_dt * this.m_impulse.y); - } - b2WeldJoint.prototype.GetReactionTorque = function (inv_dt) { - if (inv_dt === undefined) inv_dt = 0; - return inv_dt * this.m_impulse.z; - } - b2WeldJoint.prototype.b2WeldJoint = function (def) { - this.__super.b2Joint.call(this, def); - this.m_localAnchorA.SetV(def.localAnchorA); - this.m_localAnchorB.SetV(def.localAnchorB); - this.m_referenceAngle = def.referenceAngle; - this.m_impulse.SetZero(); - this.m_mass = new b2Mat33(); - } - b2WeldJoint.prototype.InitVelocityConstraints = function (step) { - var tMat; - var tX = 0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - tMat = bA.m_xf.R; - var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; - var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * rAX + tMat.col2.x * rAY); - rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY); - rAX = tX; - tMat = bB.m_xf.R; - var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; - var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * rBX + tMat.col2.x * rBY); - rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY); - rBX = tX; - var mA = bA.m_invMass; - var mB = bB.m_invMass; - var iA = bA.m_invI; - var iB = bB.m_invI; - this.m_mass.col1.x = mA + mB + rAY * rAY * iA + rBY * rBY * iB; - this.m_mass.col2.x = (-rAY * rAX * iA) - rBY * rBX * iB; - this.m_mass.col3.x = (-rAY * iA) - rBY * iB; - this.m_mass.col1.y = this.m_mass.col2.x; - this.m_mass.col2.y = mA + mB + rAX * rAX * iA + rBX * rBX * iB; - this.m_mass.col3.y = rAX * iA + rBX * iB; - this.m_mass.col1.z = this.m_mass.col3.x; - this.m_mass.col2.z = this.m_mass.col3.y; - this.m_mass.col3.z = iA + iB; - if (step.warmStarting) { - this.m_impulse.x *= step.dtRatio; - this.m_impulse.y *= step.dtRatio; - this.m_impulse.z *= step.dtRatio; - bA.m_linearVelocity.x -= mA * this.m_impulse.x; - bA.m_linearVelocity.y -= mA * this.m_impulse.y; - bA.m_angularVelocity -= iA * (rAX * this.m_impulse.y - rAY * this.m_impulse.x + this.m_impulse.z); - bB.m_linearVelocity.x += mB * this.m_impulse.x; - bB.m_linearVelocity.y += mB * this.m_impulse.y; - bB.m_angularVelocity += iB * (rBX * this.m_impulse.y - rBY * this.m_impulse.x + this.m_impulse.z); - } - else { - this.m_impulse.SetZero(); - } - } - b2WeldJoint.prototype.SolveVelocityConstraints = function (step) { - var tMat; - var tX = 0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - var vA = bA.m_linearVelocity; - var wA = bA.m_angularVelocity; - var vB = bB.m_linearVelocity; - var wB = bB.m_angularVelocity; - var mA = bA.m_invMass; - var mB = bB.m_invMass; - var iA = bA.m_invI; - var iB = bB.m_invI; - tMat = bA.m_xf.R; - var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; - var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * rAX + tMat.col2.x * rAY); - rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY); - rAX = tX; - tMat = bB.m_xf.R; - var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; - var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * rBX + tMat.col2.x * rBY); - rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY); - rBX = tX; - var Cdot1X = vB.x - wB * rBY - vA.x + wA * rAY; - var Cdot1Y = vB.y + wB * rBX - vA.y - wA * rAX; - var Cdot2 = wB - wA; - var impulse = new b2Vec3(); - this.m_mass.Solve33(impulse, (-Cdot1X), (-Cdot1Y), (-Cdot2)); - this.m_impulse.Add(impulse); - vA.x -= mA * impulse.x; - vA.y -= mA * impulse.y; - wA -= iA * (rAX * impulse.y - rAY * impulse.x + impulse.z); - vB.x += mB * impulse.x; - vB.y += mB * impulse.y; - wB += iB * (rBX * impulse.y - rBY * impulse.x + impulse.z); - bA.m_angularVelocity = wA; - bB.m_angularVelocity = wB; - } - b2WeldJoint.prototype.SolvePositionConstraints = function (baumgarte) { - if (baumgarte === undefined) baumgarte = 0; - var tMat; - var tX = 0; - var bA = this.m_bodyA; - var bB = this.m_bodyB; - tMat = bA.m_xf.R; - var rAX = this.m_localAnchorA.x - bA.m_sweep.localCenter.x; - var rAY = this.m_localAnchorA.y - bA.m_sweep.localCenter.y; - tX = (tMat.col1.x * rAX + tMat.col2.x * rAY); - rAY = (tMat.col1.y * rAX + tMat.col2.y * rAY); - rAX = tX; - tMat = bB.m_xf.R; - var rBX = this.m_localAnchorB.x - bB.m_sweep.localCenter.x; - var rBY = this.m_localAnchorB.y - bB.m_sweep.localCenter.y; - tX = (tMat.col1.x * rBX + tMat.col2.x * rBY); - rBY = (tMat.col1.y * rBX + tMat.col2.y * rBY); - rBX = tX; - var mA = bA.m_invMass; - var mB = bB.m_invMass; - var iA = bA.m_invI; - var iB = bB.m_invI; - var C1X = bB.m_sweep.c.x + rBX - bA.m_sweep.c.x - rAX; - var C1Y = bB.m_sweep.c.y + rBY - bA.m_sweep.c.y - rAY; - var C2 = bB.m_sweep.a - bA.m_sweep.a - this.m_referenceAngle; - var k_allowedStretch = 10.0 * b2Settings.b2_linearSlop; - var positionError = Math.sqrt(C1X * C1X + C1Y * C1Y); - var angularError = b2Math.Abs(C2); - if (positionError > k_allowedStretch) { - iA *= 1.0; - iB *= 1.0; - } - this.m_mass.col1.x = mA + mB + rAY * rAY * iA + rBY * rBY * iB; - this.m_mass.col2.x = (-rAY * rAX * iA) - rBY * rBX * iB; - this.m_mass.col3.x = (-rAY * iA) - rBY * iB; - this.m_mass.col1.y = this.m_mass.col2.x; - this.m_mass.col2.y = mA + mB + rAX * rAX * iA + rBX * rBX * iB; - this.m_mass.col3.y = rAX * iA + rBX * iB; - this.m_mass.col1.z = this.m_mass.col3.x; - this.m_mass.col2.z = this.m_mass.col3.y; - this.m_mass.col3.z = iA + iB; - var impulse = new b2Vec3(); - this.m_mass.Solve33(impulse, (-C1X), (-C1Y), (-C2)); - bA.m_sweep.c.x -= mA * impulse.x; - bA.m_sweep.c.y -= mA * impulse.y; - bA.m_sweep.a -= iA * (rAX * impulse.y - rAY * impulse.x + impulse.z); - bB.m_sweep.c.x += mB * impulse.x; - bB.m_sweep.c.y += mB * impulse.y; - bB.m_sweep.a += iB * (rBX * impulse.y - rBY * impulse.x + impulse.z); - bA.SynchronizeTransform(); - bB.SynchronizeTransform(); - return positionError <= b2Settings.b2_linearSlop && angularError <= b2Settings.b2_angularSlop; - } - Box2D.inherit(b2WeldJointDef, Box2D.Dynamics.Joints.b2JointDef); - b2WeldJointDef.prototype.__super = Box2D.Dynamics.Joints.b2JointDef.prototype; - b2WeldJointDef.b2WeldJointDef = function () { - Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this, arguments); - this.localAnchorA = new b2Vec2(); - this.localAnchorB = new b2Vec2(); - }; - b2WeldJointDef.prototype.b2WeldJointDef = function () { - this.__super.b2JointDef.call(this); - this.type = b2Joint.e_weldJoint; - this.referenceAngle = 0.0; - } - b2WeldJointDef.prototype.Initialize = function (bA, bB, anchor) { - this.bodyA = bA; - this.bodyB = bB; - this.localAnchorA.SetV(this.bodyA.GetLocalPoint(anchor)); - this.localAnchorB.SetV(this.bodyB.GetLocalPoint(anchor)); - this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle(); - } -})(); -(function () { - var b2DebugDraw = Box2D.Dynamics.b2DebugDraw; - b2DebugDraw.b2DebugDraw = function () { - this.m_drawScale = 1.0; - this.m_lineThickness = 1.0; - this.m_alpha = 1.0; - this.m_fillAlpha = 1.0; - this.m_xformScale = 1.0; - var __this = this; - //#WORKAROUND - this.m_sprite = { - graphics: { - clear: function () { - __this.m_ctx.clearRect(0, 0, __this.m_ctx.canvas.width, __this.m_ctx.canvas.height) - } - } - }; - }; - b2DebugDraw.prototype._color = function (color, alpha) { - return "rgba(" + ((color & 0xFF0000) >> 16) + "," + ((color & 0xFF00) >> 8) + "," + (color & 0xFF) + "," + alpha + ")"; - }; - b2DebugDraw.prototype.b2DebugDraw = function () { - this.m_drawFlags = 0; - }; - b2DebugDraw.prototype.SetFlags = function (flags) { - if (flags === undefined) flags = 0; - this.m_drawFlags = flags; - }; - b2DebugDraw.prototype.GetFlags = function () { - return this.m_drawFlags; - }; - b2DebugDraw.prototype.AppendFlags = function (flags) { - if (flags === undefined) flags = 0; - this.m_drawFlags |= flags; - }; - b2DebugDraw.prototype.ClearFlags = function (flags) { - if (flags === undefined) flags = 0; - this.m_drawFlags &= ~flags; - }; - b2DebugDraw.prototype.SetSprite = function (sprite) { - this.m_ctx = sprite; - }; - b2DebugDraw.prototype.GetSprite = function () { - return this.m_ctx; - }; - b2DebugDraw.prototype.SetDrawScale = function (drawScale) { - if (drawScale === undefined) drawScale = 0; - this.m_drawScale = drawScale; - }; - b2DebugDraw.prototype.GetDrawScale = function () { - return this.m_drawScale; - }; - b2DebugDraw.prototype.SetLineThickness = function (lineThickness) { - if (lineThickness === undefined) lineThickness = 0; - this.m_lineThickness = lineThickness; - this.m_ctx.strokeWidth = lineThickness; - }; - b2DebugDraw.prototype.GetLineThickness = function () { - return this.m_lineThickness; - }; - b2DebugDraw.prototype.SetAlpha = function (alpha) { - if (alpha === undefined) alpha = 0; - this.m_alpha = alpha; - }; - b2DebugDraw.prototype.GetAlpha = function () { - return this.m_alpha; - }; - b2DebugDraw.prototype.SetFillAlpha = function (alpha) { - if (alpha === undefined) alpha = 0; - this.m_fillAlpha = alpha; - }; - b2DebugDraw.prototype.GetFillAlpha = function () { - return this.m_fillAlpha; - }; - b2DebugDraw.prototype.SetXFormScale = function (xformScale) { - if (xformScale === undefined) xformScale = 0; - this.m_xformScale = xformScale; - }; - b2DebugDraw.prototype.GetXFormScale = function () { - return this.m_xformScale; - }; - b2DebugDraw.prototype.DrawPolygon = function (vertices, vertexCount, color) { - if (!vertexCount) return; - var s = this.m_ctx; - var drawScale = this.m_drawScale; - s.beginPath(); - s.strokeStyle = this._color(color.color, this.m_alpha); - s.moveTo(vertices[0].x * drawScale, vertices[0].y * drawScale); - for (var i = 1; i < vertexCount; i++) { - s.lineTo(vertices[i].x * drawScale, vertices[i].y * drawScale); - } - s.lineTo(vertices[0].x * drawScale, vertices[0].y * drawScale); - s.closePath(); - s.stroke(); - }; - b2DebugDraw.prototype.DrawSolidPolygon = function (vertices, vertexCount, color) { - if (!vertexCount) return; - var s = this.m_ctx; - var drawScale = this.m_drawScale; - s.beginPath(); - s.strokeStyle = this._color(color.color, this.m_alpha); - s.fillStyle = this._color(color.color, this.m_fillAlpha); - s.moveTo(vertices[0].x * drawScale, vertices[0].y * drawScale); - for (var i = 1; i < vertexCount; i++) { - s.lineTo(vertices[i].x * drawScale, vertices[i].y * drawScale); - } - s.lineTo(vertices[0].x * drawScale, vertices[0].y * drawScale); - s.closePath(); - s.fill(); - s.stroke(); - }; - b2DebugDraw.prototype.DrawCircle = function (center, radius, color) { - if (!radius) return; - var s = this.m_ctx; - var drawScale = this.m_drawScale; - s.beginPath(); - s.strokeStyle = this._color(color.color, this.m_alpha); - s.arc(center.x * drawScale, center.y * drawScale, radius * drawScale, 0, Math.PI * 2, true); - s.closePath(); - s.stroke(); - }; - b2DebugDraw.prototype.DrawSolidCircle = function (center, radius, axis, color) { - if (!radius) return; - var s = this.m_ctx, - drawScale = this.m_drawScale, - cx = center.x * drawScale, - cy = center.y * drawScale; - s.moveTo(0, 0); - s.beginPath(); - s.strokeStyle = this._color(color.color, this.m_alpha); - s.fillStyle = this._color(color.color, this.m_fillAlpha); - s.arc(cx, cy, radius * drawScale, 0, Math.PI * 2, true); - s.moveTo(cx, cy); - s.lineTo((center.x + axis.x * radius) * drawScale, (center.y + axis.y * radius) * drawScale); - s.closePath(); - s.fill(); - s.stroke(); - }; - b2DebugDraw.prototype.DrawSegment = function (p1, p2, color) { - var s = this.m_ctx, - drawScale = this.m_drawScale; - s.strokeStyle = this._color(color.color, this.m_alpha); - s.beginPath(); - s.moveTo(p1.x * drawScale, p1.y * drawScale); - s.lineTo(p2.x * drawScale, p2.y * drawScale); - s.closePath(); - s.stroke(); - }; - b2DebugDraw.prototype.DrawTransform = function (xf) { - var s = this.m_ctx, - drawScale = this.m_drawScale; - s.beginPath(); - s.strokeStyle = this._color(0xff0000, this.m_alpha); - s.moveTo(xf.position.x * drawScale, xf.position.y * drawScale); - s.lineTo((xf.position.x + this.m_xformScale * xf.R.col1.x) * drawScale, (xf.position.y + this.m_xformScale * xf.R.col1.y) * drawScale); - - s.strokeStyle = this._color(0xff00, this.m_alpha); - s.moveTo(xf.position.x * drawScale, xf.position.y * drawScale); - s.lineTo((xf.position.x + this.m_xformScale * xf.R.col2.x) * drawScale, (xf.position.y + this.m_xformScale * xf.R.col2.y) * drawScale); - s.closePath(); - s.stroke(); - }; -})(); //post-definitions -var i; -for (i = 0; i < Box2D.postDefs.length; ++i) Box2D.postDefs[i](); -delete Box2D.postDefs; - -if (typeof require !== 'undefined' && typeof module !== 'undefined') { - module.exports = Box2D; -} diff --git a/external/chipmunk/chipmunk.js b/external/chipmunk/chipmunk.js index 3be84bfc61..e69de29bb2 100644 --- a/external/chipmunk/chipmunk.js +++ b/external/chipmunk/chipmunk.js @@ -1,6196 +0,0 @@ -(function(){ -/* Copyright (c) 2007 Scott Lembcke - * - * 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. - */ - -Object.create = Object.create || function(o) { - function F() {} - F.prototype = o; - return new F(); -}; - -//var VERSION = CP_VERSION_MAJOR + "." + CP_VERSION_MINOR + "." + CP_VERSION_RELEASE; - -var cp; -if(typeof exports === 'undefined'){ - cp = {}; - - if(typeof window === 'object'){ - window["cp"] = cp; - } -} else { - cp = exports; -} - -var assert = function(value, message) -{ - if (!value) { - throw new Error('Assertion failed: ' + message); - } -}; - -var assertSoft = function(value, message) -{ - if(!value && console && console.warn) { - console.warn("ASSERTION FAILED: " + message); - if(console.trace) { - console.trace(); - } - } -}; - -var mymin = function(a, b) -{ - return a < b ? a : b; -}; -var mymax = function(a, b) -{ - return a > b ? a : b; -}; - -var min, max; -if (typeof window === 'object' && window.navigator.userAgent.indexOf('Firefox') > -1){ - // On firefox, Math.min and Math.max are really fast: - // http://jsperf.com/math-vs-greater-than/8 - min = Math.min; - max = Math.max; -} else { - // On chrome and safari, Math.min / max are slooow. The ternery operator above is faster - // than the builtins because we only have to deal with 2 arguments that are always numbers. - min = mymin; - max = mymax; -} - -/* The hashpair function takes two numbers and returns a hash code for them. - * Required that hashPair(a, b) === hashPair(b, a). - * Chipmunk's hashPair function is defined as: - * #define CP_HASH_COEF (3344921057ul) - * #define CP_HASH_PAIR(A, B) ((cpHashValue)(A)*CP_HASH_COEF ^ (cpHashValue)(B)*CP_HASH_COEF) - * But thats not suitable in javascript because multiplying by a large number will make the number - * a large float. - * - * The result of hashPair is used as the key in objects, so it returns a string. - */ -var hashPair = function(a, b) -{ - //assert(typeof(a) === 'number', "HashPair used on something not a number"); - return a < b ? a + ' ' + b : b + ' ' + a; -}; - -var deleteObjFromList = function(arr, obj) -{ - for(var i=0; i> 1; - for(var i=1; i maxx || (x == maxx && y > maxy)){ - maxx = x; - maxy = y; - end = i; - } - } - return [start, end]; -}; - -var SWAP = function(arr, idx1, idx2) -{ - var tmp = arr[idx1*2]; - arr[idx1*2] = arr[idx2*2]; - arr[idx2*2] = tmp; - - tmp = arr[idx1*2+1]; - arr[idx1*2+1] = arr[idx2*2+1]; - arr[idx2*2+1] = tmp; -}; - -var QHullPartition = function(verts, offs, count, a, b, tol) -{ - if(count === 0) return 0; - - var max = 0; - var pivot = offs; - - var delta = vsub(b, a); - var valueTol = tol * vlength(delta); - - var head = offs; - for(var tail = offs+count-1; head <= tail;){ - var v = new Vect(verts[head * 2], verts[head * 2 + 1]); - var value = vcross(delta, vsub(v, a)); - if(value > valueTol){ - if(value > max){ - max = value; - pivot = head; - } - - head++; - } else { - SWAP(verts, head, tail); - tail--; - } - } - - // move the new pivot to the front if it's not already there. - if(pivot != offs) SWAP(verts, offs, pivot); - return head - offs; -}; - -var QHullReduce = function(tol, verts, offs, count, a, pivot, b, resultPos) -{ - if(count < 0){ - return 0; - } else if(count == 0) { - verts[resultPos*2] = pivot.x; - verts[resultPos*2+1] = pivot.y; - return 1; - } else { - var left_count = QHullPartition(verts, offs, count, a, pivot, tol); - var left = new Vect(verts[offs*2], verts[offs*2+1]); - var index = QHullReduce(tol, verts, offs + 1, left_count - 1, a, left, pivot, resultPos); - - var pivotPos = resultPos + index++; - verts[pivotPos*2] = pivot.x; - verts[pivotPos*2+1] = pivot.y; - - var right_count = QHullPartition(verts, offs + left_count, count - left_count, pivot, b, tol); - var right = new Vect(verts[(offs+left_count)*2], verts[(offs+left_count)*2+1]); - return index + QHullReduce(tol, verts, offs + left_count + 1, right_count - 1, pivot, right, b, resultPos + index); - } -}; - -// QuickHull seemed like a neat algorithm, and efficient-ish for large input sets. -// My implementation performs an in place reduction using the result array as scratch space. -// -// Pass an Array into result to put the result of the calculation there. Otherwise, pass null -// and the verts list will be edited in-place. -// -// Expects the verts to be described in the same way as cpPolyShape - which is to say, it should -// be a list of [x1,y1,x2,y2,x3,y3,...]. -// -// tolerance is in world coordinates. Eg, 2. -cp.convexHull = function(verts, result, tolerance) -{ - if(result){ - // Copy the line vertexes into the empty part of the result polyline to use as a scratch buffer. - for (var i = 0; i < verts.length; i++){ - result[i] = verts[i]; - } - } else { - // If a result array was not specified, reduce the input instead. - result = verts; - } - - // Degenerate case, all points are the same. - var indexes = loopIndexes(verts); - var start = indexes[0], end = indexes[1]; - if(start == end){ - //if(first) (*first) = 0; - result.length = 2; - return result; - } - - SWAP(result, 0, start); - SWAP(result, 1, end == 0 ? start : end); - - var a = new Vect(result[0], result[1]); - var b = new Vect(result[2], result[3]); - - var count = verts.length >> 1; - //if(first) (*first) = start; - var resultCount = QHullReduce(tolerance, result, 2, count - 2, a, b, a, 1) + 1; - result.length = resultCount*2; - - assertSoft(polyValidate(result), - "Internal error: cpConvexHull() and cpPolyValidate() did not agree." + - "Please report this error with as much info as you can."); - return result; -}; - -/// Clamp @c f to be between @c min and @c max. -var clamp = function(f, minv, maxv) -{ - return min(max(f, minv), maxv); -}; - -/// Clamp @c f to be between 0 and 1. -var clamp01 = function(f) -{ - return max(0, min(f, 1)); -}; - -/// Linearly interpolate (or extrapolate) between @c f1 and @c f2 by @c t percent. -var lerp = function(f1, f2, t) -{ - return f1*(1 - t) + f2*t; -}; - -/// Linearly interpolate from @c f1 to @c f2 by no more than @c d. -var lerpconst = function(f1, f2, d) -{ - return f1 + clamp(f2 - f1, -d, d); -}; - -/* Copyright (c) 2007 Scott Lembcke - * - * 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. - */ - -// I'm using an array tuple here because (at time of writing) its about 3x faster -// than an object on firefox, and the same speed on chrome. - -//var numVects = 0; - -var Vect = cp.Vect = function(x, y) -{ - this.x = x; - this.y = y; - //numVects++; - -// var s = new Error().stack; -// traces[s] = traces[s] ? traces[s]+1 : 1; -}; - -cp.v = function (x,y) { return new Vect(x, y) }; - -var vzero = cp.vzero = new Vect(0,0); - -// The functions below *could* be rewritten to be instance methods on Vect. I don't -// know how that would effect performance. For now, I'm keeping the JS similar to -// the original C code. - -/// Vector dot product. -var vdot = cp.v.dot = function(v1, v2) -{ - return v1.x*v2.x + v1.y*v2.y; -}; - -var vdot2 = function(x1, y1, x2, y2) -{ - return x1*x2 + y1*y2; -}; - -/// Returns the length of v. -var vlength = cp.v.len = function(v) -{ - return Math.sqrt(vdot(v, v)); -}; - -var vlength2 = cp.v.len2 = function(x, y) -{ - return Math.sqrt(x*x + y*y); -}; - -/// Check if two vectors are equal. (Be careful when comparing floating point numbers!) -var veql = cp.v.eql = function(v1, v2) -{ - return (v1.x === v2.x && v1.y === v2.y); -}; - -/// Add two vectors -var vadd = cp.v.add = function(v1, v2) -{ - return new Vect(v1.x + v2.x, v1.y + v2.y); -}; - -Vect.prototype.add = function(v2) -{ - this.x += v2.x; - this.y += v2.y; - return this; -}; - -/// Subtract two vectors. -var vsub = cp.v.sub = function(v1, v2) -{ - return new Vect(v1.x - v2.x, v1.y - v2.y); -}; - -Vect.prototype.sub = function(v2) -{ - this.x -= v2.x; - this.y -= v2.y; - return this; -}; - -/// Negate a vector. -var vneg = cp.v.neg = function(v) -{ - return new Vect(-v.x, -v.y); -}; - -Vect.prototype.neg = function() -{ - this.x = -this.x; - this.y = -this.y; - return this; -}; - -/// Scalar multiplication. -var vmult = cp.v.mult = function(v, s) -{ - return new Vect(v.x*s, v.y*s); -}; - -Vect.prototype.mult = function(s) -{ - this.x *= s; - this.y *= s; - return this; -}; - -/// 2D vector cross product analog. -/// The cross product of 2D vectors results in a 3D vector with only a z component. -/// This function returns the magnitude of the z value. -var vcross = cp.v.cross = function(v1, v2) -{ - return v1.x*v2.y - v1.y*v2.x; -}; - -var vcross2 = function(x1, y1, x2, y2) -{ - return x1*y2 - y1*x2; -}; - -/// Returns a perpendicular vector. (90 degree rotation) -var vperp = cp.v.perp = function(v) -{ - return new Vect(-v.y, v.x); -}; - -/// Returns a perpendicular vector. (-90 degree rotation) -var vpvrperp = cp.v.pvrperp = function(v) -{ - return new Vect(v.y, -v.x); -}; - -/// Returns the vector projection of v1 onto v2. -var vproject = cp.v.project = function(v1, v2) -{ - return vmult(v2, vdot(v1, v2)/vlengthsq(v2)); -}; - -Vect.prototype.project = function(v2) -{ - this.mult(vdot(this, v2) / vlengthsq(v2)); - return this; -}; - -/// Uses complex number multiplication to rotate v1 by v2. Scaling will occur if v1 is not a unit vector. -var vrotate = cp.v.rotate = function(v1, v2) -{ - return new Vect(v1.x*v2.x - v1.y*v2.y, v1.x*v2.y + v1.y*v2.x); -}; - -Vect.prototype.rotate = function(v2) -{ - this.x = this.x * v2.x - this.y * v2.y; - this.y = this.x * v2.y + this.y * v2.x; - return this; -}; - -/// Inverse of vrotate(). -var vunrotate = cp.v.unrotate = function(v1, v2) -{ - return new Vect(v1.x*v2.x + v1.y*v2.y, v1.y*v2.x - v1.x*v2.y); -}; - -/// Returns the squared length of v. Faster than vlength() when you only need to compare lengths. -var vlengthsq = cp.v.lengthsq = function(v) -{ - return vdot(v, v); -}; - -var vlengthsq2 = cp.v.lengthsq2 = function(x, y) -{ - return x*x + y*y; -}; - -/// Linearly interpolate between v1 and v2. -var vlerp = cp.v.lerp = function(v1, v2, t) -{ - return vadd(vmult(v1, 1 - t), vmult(v2, t)); -}; - -/// Returns a normalized copy of v. -var vnormalize = cp.v.normalize = function(v) -{ - return vmult(v, 1/vlength(v)); -}; - -/// Returns a normalized copy of v or vzero if v was already vzero. Protects against divide by zero errors. -var vnormalize_safe = cp.v.normalize_safe = function(v) -{ - return (v.x === 0 && v.y === 0 ? vzero : vnormalize(v)); -}; - -/// Clamp v to length len. -var vclamp = cp.v.clamp = function(v, len) -{ - return (vdot(v,v) > len*len) ? vmult(vnormalize(v), len) : v; -}; - -/// Linearly interpolate between v1 towards v2 by distance d. -var vlerpconst = cp.v.lerpconst = function(v1, v2, d) -{ - return vadd(v1, vclamp(vsub(v2, v1), d)); -}; - -/// Returns the distance between v1 and v2. -var vdist = cp.v.dist = function(v1, v2) -{ - return vlength(vsub(v1, v2)); -}; - -/// Returns the squared distance between v1 and v2. Faster than vdist() when you only need to compare distances. -var vdistsq = cp.v.distsq = function(v1, v2) -{ - return vlengthsq(vsub(v1, v2)); -}; - -/// Returns true if the distance between v1 and v2 is less than dist. -var vnear = cp.v.near = function(v1, v2, dist) -{ - return vdistsq(v1, v2) < dist*dist; -}; - -/// Spherical linearly interpolate between v1 and v2. -var vslerp = cp.v.slerp = function(v1, v2, t) -{ - var omega = Math.acos(vdot(v1, v2)); - - if(omega) { - var denom = 1/Math.sin(omega); - return vadd(vmult(v1, Math.sin((1 - t)*omega)*denom), vmult(v2, Math.sin(t*omega)*denom)); - } else { - return v1; - } -}; - -/// Spherical linearly interpolate between v1 towards v2 by no more than angle a radians -var vslerpconst = cp.v.slerpconst = function(v1, v2, a) -{ - var angle = Math.acos(vdot(v1, v2)); - return vslerp(v1, v2, min(a, angle)/angle); -}; - -/// Returns the unit length vector for the given angle (in radians). -var vforangle = cp.v.forangle = function(a) -{ - return new Vect(Math.cos(a), Math.sin(a)); -}; - -/// Returns the angular direction v is pointing in (in radians). -var vtoangle = cp.v.toangle = function(v) -{ - return Math.atan2(v.y, v.x); -}; - -/// Returns a string representation of v. Intended mostly for debugging purposes and not production use. -var vstr = cp.v.str = function(v) -{ - return "(" + v.x.toFixed(3) + ", " + v.y.toFixed(3) + ")"; -}; - -/* Copyright (c) 2007 Scott Lembcke - * - * 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. - */ - -/// Chipmunk's axis-aligned 2D bounding box type along with a few handy routines. - -var numBB = 0; - -// Bounding boxes are JS objects with {l, b, r, t} = left, bottom, right, top, respectively. -var BB = cp.BB = function(l, b, r, t) -{ - this.l = l; - this.b = b; - this.r = r; - this.t = t; - - numBB++; -}; - -cp.bb = function(l, b, r, t) { return new BB(l, b, r, t); }; - -var bbNewForCircle = function(p, r) -{ - return new BB( - p.x - r, - p.y - r, - p.x + r, - p.y + r - ); -}; - -/// Returns true if @c a and @c b intersect. -var bbIntersects = function(a, b) -{ - return (a.l <= b.r && b.l <= a.r && a.b <= b.t && b.b <= a.t); -}; -var bbIntersects2 = function(bb, l, b, r, t) -{ - return (bb.l <= r && l <= bb.r && bb.b <= t && b <= bb.t); -}; - -/// Returns true if @c other lies completely within @c bb. -var bbContainsBB = function(bb, other) -{ - return (bb.l <= other.l && bb.r >= other.r && bb.b <= other.b && bb.t >= other.t); -}; - -/// Returns true if @c bb contains @c v. -var bbContainsVect = function(bb, v) -{ - return (bb.l <= v.x && bb.r >= v.x && bb.b <= v.y && bb.t >= v.y); -}; -var bbContainsVect2 = function(l, b, r, t, v) -{ - return (l <= v.x && r >= v.x && b <= v.y && t >= v.y); -}; - -/// Returns a bounding box that holds both bounding boxes. -var bbMerge = function(a, b){ - return new BB( - min(a.l, b.l), - min(a.b, b.b), - max(a.r, b.r), - max(a.t, b.t) - ); -}; - -/// Returns a bounding box that holds both @c bb and @c v. -var bbExpand = function(bb, v){ - return new BB( - min(bb.l, v.x), - min(bb.b, v.y), - max(bb.r, v.x), - max(bb.t, v.y) - ); -}; - -/// Returns the area of the bounding box. -var bbArea = function(bb) -{ - return (bb.r - bb.l)*(bb.t - bb.b); -}; - -/// Merges @c a and @c b and returns the area of the merged bounding box. -var bbMergedArea = function(a, b) -{ - return (max(a.r, b.r) - min(a.l, b.l))*(max(a.t, b.t) - min(a.b, b.b)); -}; - -var bbMergedArea2 = function(bb, l, b, r, t) -{ - return (max(bb.r, r) - min(bb.l, l))*(max(bb.t, t) - min(bb.b, b)); -}; - -/// Return true if the bounding box intersects the line segment with ends @c a and @c b. -var bbIntersectsSegment = function(bb, a, b) -{ - return (bbSegmentQuery(bb, a, b) != Infinity); -}; - -/// Clamp a vector to a bounding box. -var bbClampVect = function(bb, v) -{ - var x = min(max(bb.l, v.x), bb.r); - var y = min(max(bb.b, v.y), bb.t); - return new Vect(x, y); -}; - -// TODO edge case issue -/// Wrap a vector to a bounding box. -var bbWrapVect = function(bb, v) -{ - var ix = Math.abs(bb.r - bb.l); - var modx = (v.x - bb.l) % ix; - var x = (modx > 0) ? modx : modx + ix; - - var iy = Math.abs(bb.t - bb.b); - var mody = (v.y - bb.b) % iy; - var y = (mody > 0) ? mody : mody + iy; - - return new Vect(x + bb.l, y + bb.b); -}; -/* Copyright (c) 2007 Scott Lembcke - * - * 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. - */ - -/// Segment query info struct. -/* These are created using literals where needed. -typedef struct cpSegmentQueryInfo { - /// The shape that was hit, null if no collision occured. - cpShape *shape; - /// The normalized distance along the query segment in the range [0, 1]. - cpFloat t; - /// The normal of the surface hit. - cpVect n; -} cpSegmentQueryInfo; -*/ - -var shapeIDCounter = 0; - -var CP_NO_GROUP = cp.NO_GROUP = 0; -var CP_ALL_LAYERS = cp.ALL_LAYERS = ~0; - -cp.resetShapeIdCounter = function() -{ - shapeIDCounter = 0; -}; - -/// The cpShape struct defines the shape of a rigid body. -// -/// Opaque collision shape struct. Do not create directly - instead use -/// PolyShape, CircleShape and SegmentShape. -var Shape = cp.Shape = function(body) { - /// The rigid body this collision shape is attached to. - this.body = body; - - /// The current bounding box of the shape. - this.bb_l = this.bb_b = this.bb_r = this.bb_t = 0; - - this.hashid = shapeIDCounter++; - - /// Sensor flag. - /// Sensor shapes call collision callbacks but don't produce collisions. - this.sensor = false; - - /// Coefficient of restitution. (elasticity) - this.e = 0; - /// Coefficient of friction. - this.u = 0; - /// Surface velocity used when solving for friction. - this.surface_v = vzero; - - /// Collision type of this shape used when picking collision handlers. - this.collision_type = 0; - /// Group of this shape. Shapes in the same group don't collide. - this.group = 0; - // Layer bitmask for this shape. Shapes only collide if the bitwise and of their layers is non-zero. - this.layers = CP_ALL_LAYERS; - - this.space = null; - - // Copy the collision code from the prototype into the actual object. This makes collision - // function lookups slightly faster. - this.collisionCode = this.collisionCode; -}; - -Shape.prototype.setElasticity = function(e) { this.e = e; }; -Shape.prototype.setFriction = function(u) { this.body.activate(); this.u = u; }; -Shape.prototype.setLayers = function(layers) { this.body.activate(); this.layers = layers; }; -Shape.prototype.setSensor = function(sensor) { this.body.activate(); this.sensor = sensor; }; -Shape.prototype.setCollisionType = function(collision_type) { this.body.activate(); this.collision_type = collision_type; }; -Shape.prototype.getBody = function() { return this.body; }; - -Shape.prototype.active = function() -{ -// return shape->prev || (shape->body && shape->body->shapeList == shape); - return this.body && this.body.shapeList.indexOf(this) !== -1; -}; - -Shape.prototype.setBody = function(body) -{ - assert(!this.active(), "You cannot change the body on an active shape. You must remove the shape from the space before changing the body."); - this.body = body; -}; - -Shape.prototype.cacheBB = function() -{ - return this.update(this.body.p, this.body.rot); -}; - -Shape.prototype.update = function(pos, rot) -{ - assert(!isNaN(rot.x), 'Rotation is NaN'); - assert(!isNaN(pos.x), 'Position is NaN'); - this.cacheData(pos, rot); -}; - -Shape.prototype.pointQuery = function(p) -{ - var info = this.nearestPointQuery(p); - if (info.d < 0) return info; -}; - -Shape.prototype.getBB = function() -{ - return new BB(this.bb_l, this.bb_b, this.bb_r, this.bb_t); -}; - -/* Not implemented - all these getters and setters. Just edit the object directly. -CP_DefineShapeStructGetter(cpBody*, body, Body); -void cpShapeSetBody(cpShape *shape, cpBody *body); - -CP_DefineShapeStructGetter(cpBB, bb, BB); -CP_DefineShapeStructProperty(cpBool, sensor, Sensor, cpTrue); -CP_DefineShapeStructProperty(cpFloat, e, Elasticity, cpFalse); -CP_DefineShapeStructProperty(cpFloat, u, Friction, cpTrue); -CP_DefineShapeStructProperty(cpVect, surface_v, SurfaceVelocity, cpTrue); -CP_DefineShapeStructProperty(cpDataPointer, data, UserData, cpFalse); -CP_DefineShapeStructProperty(cpCollisionType, collision_type, CollisionType, cpTrue); -CP_DefineShapeStructProperty(cpGroup, group, Group, cpTrue); -CP_DefineShapeStructProperty(cpLayers, layers, Layers, cpTrue); -*/ - -/// Extended point query info struct. Returned from calling pointQuery on a shape. -var PointQueryExtendedInfo = function(shape) -{ - /// Shape that was hit, NULL if no collision occurred. - this.shape = shape; - /// Depth of the point inside the shape. - this.d = Infinity; - /// Direction of minimum norm to the shape's surface. - this.n = vzero; -}; - -var NearestPointQueryInfo = function(shape, p, d) -{ - /// The nearest shape, NULL if no shape was within range. - this.shape = shape; - /// The closest point on the shape's surface. (in world space coordinates) - this.p = p; - /// The distance to the point. The distance is negative if the point is inside the shape. - this.d = d; -}; - -var SegmentQueryInfo = function(shape, t, n) -{ - /// The shape that was hit, NULL if no collision occured. - this.shape = shape; - /// The normalized distance along the query segment in the range [0, 1]. - this.t = t; - /// The normal of the surface hit. - this.n = n; -}; - -/// Get the hit point for a segment query. -SegmentQueryInfo.prototype.hitPoint = function(start, end) -{ - return vlerp(start, end, this.t); -}; - -/// Get the hit distance for a segment query. -SegmentQueryInfo.prototype.hitDist = function(start, end) -{ - return vdist(start, end) * this.t; -}; - -// Circles. - -var CircleShape = cp.CircleShape = function(body, radius, offset) -{ - this.c = this.tc = offset; - this.r = radius; - - this.type = 'circle'; - - Shape.call(this, body); -}; - -CircleShape.prototype = Object.create(Shape.prototype); - -CircleShape.prototype.cacheData = function(p, rot) -{ - //var c = this.tc = vadd(p, vrotate(this.c, rot)); - var c = this.tc = vrotate(this.c, rot).add(p); - //this.bb = bbNewForCircle(c, this.r); - var r = this.r; - this.bb_l = c.x - r; - this.bb_b = c.y - r; - this.bb_r = c.x + r; - this.bb_t = c.y + r; -}; - -/// Test if a point lies within a shape. -/*CircleShape.prototype.pointQuery = function(p) -{ - var delta = vsub(p, this.tc); - var distsq = vlengthsq(delta); - var r = this.r; - - if(distsq < r*r){ - var info = new PointQueryExtendedInfo(this); - - var dist = Math.sqrt(distsq); - info.d = r - dist; - info.n = vmult(delta, 1/dist); - return info; - } -};*/ - -CircleShape.prototype.nearestPointQuery = function(p) -{ - var deltax = p.x - this.tc.x; - var deltay = p.y - this.tc.y; - var d = vlength2(deltax, deltay); - var r = this.r; - - var nearestp = new Vect(this.tc.x + deltax * r/d, this.tc.y + deltay * r/d); - return new NearestPointQueryInfo(this, nearestp, d - r); -}; - -var circleSegmentQuery = function(shape, center, r, a, b, info) -{ - // offset the line to be relative to the circle - a = vsub(a, center); - b = vsub(b, center); - - var qa = vdot(a, a) - 2*vdot(a, b) + vdot(b, b); - var qb = -2*vdot(a, a) + 2*vdot(a, b); - var qc = vdot(a, a) - r*r; - - var det = qb*qb - 4*qa*qc; - - if(det >= 0) - { - var t = (-qb - Math.sqrt(det))/(2*qa); - if(0 <= t && t <= 1){ - return new SegmentQueryInfo(shape, t, vnormalize(vlerp(a, b, t))); - } - } -}; - -CircleShape.prototype.segmentQuery = function(a, b) -{ - return circleSegmentQuery(this, this.tc, this.r, a, b); -}; - -// The C API has these, and also getters. Its not idiomatic to -// write getters and setters in JS. -/* -CircleShape.prototype.setRadius = function(radius) -{ - this.r = radius; -} - -CircleShape.prototype.setOffset = function(offset) -{ - this.c = offset; -}*/ - -// Segment shape - -var SegmentShape = cp.SegmentShape = function(body, a, b, r) -{ - this.a = a; - this.b = b; - this.n = vperp(vnormalize(vsub(b, a))); - - this.ta = this.tb = this.tn = null; - - this.r = r; - - this.a_tangent = vzero; - this.b_tangent = vzero; - - this.type = 'segment'; - Shape.call(this, body); -}; - -SegmentShape.prototype = Object.create(Shape.prototype); - -SegmentShape.prototype.cacheData = function(p, rot) -{ - this.ta = vadd(p, vrotate(this.a, rot)); - this.tb = vadd(p, vrotate(this.b, rot)); - this.tn = vrotate(this.n, rot); - - var l,r,b,t; - - if(this.ta.x < this.tb.x){ - l = this.ta.x; - r = this.tb.x; - } else { - l = this.tb.x; - r = this.ta.x; - } - - if(this.ta.y < this.tb.y){ - b = this.ta.y; - t = this.tb.y; - } else { - b = this.tb.y; - t = this.ta.y; - } - - var rad = this.r; - - this.bb_l = l - rad; - this.bb_b = b - rad; - this.bb_r = r + rad; - this.bb_t = t + rad; -}; - -SegmentShape.prototype.nearestPointQuery = function(p) -{ - var closest = closestPointOnSegment(p, this.ta, this.tb); - - var deltax = p.x - closest.x; - var deltay = p.y - closest.y; - var d = vlength2(deltax, deltay); - var r = this.r; - - var nearestp = (d ? vadd(closest, vmult(new Vect(deltax, deltay), r/d)) : closest); - return new NearestPointQueryInfo(this, nearestp, d - r); -}; - -SegmentShape.prototype.segmentQuery = function(a, b) -{ - var n = this.tn; - var d = vdot(vsub(this.ta, a), n); - var r = this.r; - - var flipped_n = (d > 0 ? vneg(n) : n); - var n_offset = vsub(vmult(flipped_n, r), a); - - var seg_a = vadd(this.ta, n_offset); - var seg_b = vadd(this.tb, n_offset); - var delta = vsub(b, a); - - if(vcross(delta, seg_a)*vcross(delta, seg_b) <= 0){ - var d_offset = d + (d > 0 ? -r : r); - var ad = -d_offset; - var bd = vdot(delta, n) - d_offset; - - if(ad*bd < 0){ - return new SegmentQueryInfo(this, ad/(ad - bd), flipped_n); - } - } else if(r !== 0){ - var info1 = circleSegmentQuery(this, this.ta, this.r, a, b); - var info2 = circleSegmentQuery(this, this.tb, this.r, a, b); - - if (info1){ - return info2 && info2.t < info1.t ? info2 : info1; - } else { - return info2; - } - } -}; - -SegmentShape.prototype.setNeighbors = function(prev, next) -{ - this.a_tangent = vsub(prev, this.a); - this.b_tangent = vsub(next, this.b); -}; - -SegmentShape.prototype.setEndpoints = function(a, b) -{ - this.a = a; - this.b = b; - this.n = vperp(vnormalize(vsub(b, a))); -}; - -/* -cpSegmentShapeSetRadius(cpShape *shape, cpFloat radius) -{ - this.r = radius; -}*/ - -/* -CP_DeclareShapeGetter(cpSegmentShape, cpVect, A); -CP_DeclareShapeGetter(cpSegmentShape, cpVect, B); -CP_DeclareShapeGetter(cpSegmentShape, cpVect, Normal); -CP_DeclareShapeGetter(cpSegmentShape, cpFloat, Radius); -*/ - -/* Copyright (c) 2007 Scott Lembcke - * - * 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. - */ - -/// Check that a set of vertexes is convex and has a clockwise winding. -var polyValidate = function(verts) -{ - var len = verts.length; - for(var i=0; i 0){ - if(vcross2(bx - ax, by - ay, cx - bx, cy - by) > 0){ - return false; - } - } - - return true; -}; - -/// Initialize a polygon shape. -/// The vertexes must be convex and have a clockwise winding. -var PolyShape = cp.PolyShape = function(body, verts, offset) -{ - this.setVerts(verts, offset); - this.type = 'poly'; - Shape.call(this, body); -}; - -PolyShape.prototype = Object.create(Shape.prototype); - -var SplittingPlane = function(n, d) -{ - this.n = n; - this.d = d; -}; - -SplittingPlane.prototype.compare = function(v) -{ - return vdot(this.n, v) - this.d; -}; - -PolyShape.prototype.setVerts = function(verts, offset) -{ - assert(verts.length >= 4, "Polygons require some verts"); - assert(typeof(verts[0]) === 'number', - 'Polygon verticies should be specified in a flattened list (eg [x1,y1,x2,y2,x3,y3,...])'); - - // Fail if the user attempts to pass a concave poly, or a bad winding. - assert(polyValidate(verts), "Polygon is concave or has a reversed winding. Consider using cpConvexHull()"); - - var len = verts.length; - var numVerts = len >> 1; - - // This a pretty bad way to do this in javascript. As a first pass, I want to keep - // the code similar to the C. - this.verts = new Array(len); - this.tVerts = new Array(len); - this.planes = new Array(numVerts); - this.tPlanes = new Array(numVerts); - - for(var i=0; i>1] = new SplittingPlane(n, vdot2(n.x, n.y, ax, ay)); - this.tPlanes[i>>1] = new SplittingPlane(new Vect(0,0), 0); - } -}; - -/// Initialize a box shaped polygon shape. -var BoxShape = cp.BoxShape = function(body, width, height) -{ - var hw = width/2; - var hh = height/2; - - return BoxShape2(body, new BB(-hw, -hh, hw, hh)); -}; - -/// Initialize an offset box shaped polygon shape. -var BoxShape2 = cp.BoxShape2 = function(body, box) -{ - var verts = [ - box.l, box.b, - box.l, box.t, - box.r, box.t, - box.r, box.b - ]; - - return new PolyShape(body, verts, vzero); -}; - -PolyShape.prototype.transformVerts = function(p, rot) -{ - var src = this.verts; - var dst = this.tVerts; - - var l = Infinity, r = -Infinity; - var b = Infinity, t = -Infinity; - - for(var i=0; i (' + vx + ',' + vy + ')'); - - dst[i] = vx; - dst[i+1] = vy; - - l = min(l, vx); - r = max(r, vx); - b = min(b, vy); - t = max(t, vy); - } - - this.bb_l = l; - this.bb_b = b; - this.bb_r = r; - this.bb_t = t; -}; - -PolyShape.prototype.transformAxes = function(p, rot) -{ - var src = this.planes; - var dst = this.tPlanes; - - for(var i=0; i 0) outside = true; - - var v1x = verts[i*2]; - var v1y = verts[i*2 + 1]; - var closest = closestPointOnSegment2(p.x, p.y, v0x, v0y, v1x, v1y); - - var dist = vdist(p, closest); - if(dist < minDist){ - minDist = dist; - closestPoint = closest; - } - - v0x = v1x; - v0y = v1y; - } - - return new NearestPointQueryInfo(this, closestPoint, (outside ? minDist : -minDist)); -}; - -PolyShape.prototype.segmentQuery = function(a, b) -{ - var axes = this.tPlanes; - var verts = this.tVerts; - var numVerts = axes.length; - var len = numVerts * 2; - - for(var i=0; i an) continue; - - var bn = vdot(b, n); - var t = (axes[i].d - an)/(bn - an); - if(t < 0 || 1 < t) continue; - - var point = vlerp(a, b, t); - var dt = -vcross(n, point); - var dtMin = -vcross2(n.x, n.y, verts[i*2], verts[i*2+1]); - var dtMax = -vcross2(n.x, n.y, verts[(i*2+2)%len], verts[(i*2+3)%len]); - - if(dtMin <= dt && dt <= dtMax){ - // josephg: In the original C code, this function keeps - // looping through axes after finding a match. I *think* - // this code is equivalent... - return new SegmentQueryInfo(this, t, n); - } - } -}; - -PolyShape.prototype.valueOnAxis = function(n, d) -{ - var verts = this.tVerts; - var m = vdot2(n.x, n.y, verts[0], verts[1]); - - for(var i=2; i 0) return false; - } - - return true; -}; - -PolyShape.prototype.containsVertPartial = function(vx, vy, n) -{ - var planes = this.tPlanes; - - for(var i=0; i 0) return false; - } - - return true; -}; - -// These methods are provided for API compatibility with Chipmunk. I recommend against using -// them - just access the poly.verts list directly. -PolyShape.prototype.getNumVerts = function() { return this.verts.length / 2; }; -PolyShape.prototype.getVert = function(i) -{ - return new Vect(this.verts[i * 2], this.verts[i * 2 + 1]); -}; - -/* Copyright (c) 2007 Scott Lembcke - * - * 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. - */ - -/// @defgroup cpBody cpBody -/// Chipmunk's rigid body type. Rigid bodies hold the physical properties of an object like -/// it's mass, and position and velocity of it's center of gravity. They don't have an shape on their own. -/// They are given a shape by creating collision shapes (cpShape) that point to the body. -/// @{ - -var Body = cp.Body = function(m, i) { - /// Mass of the body. - /// Must agree with cpBody.m_inv! Use body.setMass() when changing the mass for this reason. - //this.m; - /// Mass inverse. - //this.m_inv; - - /// Moment of inertia of the body. - /// Must agree with cpBody.i_inv! Use body.setMoment() when changing the moment for this reason. - //this.i; - /// Moment of inertia inverse. - //this.i_inv; - - /// Position of the rigid body's center of gravity. - this.p = new Vect(0,0); - /// Velocity of the rigid body's center of gravity. - this.vx = this.vy = 0; - /// Force acting on the rigid body's center of gravity. - this.f = new Vect(0,0); - - /// Rotation of the body around it's center of gravity in radians. - /// Must agree with cpBody.rot! Use cpBodySetAngle() when changing the angle for this reason. - //this.a; - /// Angular velocity of the body around it's center of gravity in radians/second. - this.w = 0; - /// Torque applied to the body around it's center of gravity. - this.t = 0; - - /// Cached unit length vector representing the angle of the body. - /// Used for fast rotations using cpvrotate(). - //cpVect rot; - - /// Maximum velocity allowed when updating the velocity. - this.v_limit = Infinity; - /// Maximum rotational rate (in radians/second) allowed when updating the angular velocity. - this.w_limit = Infinity; - - // This stuff is all private. - this.v_biasx = this.v_biasy = 0; - this.w_bias = 0; - - this.space = null; - - this.shapeList = []; - this.arbiterList = null; // These are both wacky linked lists. - this.constraintList = null; - - // This stuff is used to track information on the collision graph. - this.nodeRoot = null; - this.nodeNext = null; - this.nodeIdleTime = 0; - - // Set this.m and this.m_inv - this.setMass(m); - - // Set this.i and this.i_inv - this.setMoment(i); - - // Set this.a and this.rot - this.rot = new Vect(0,0); - this.setAngle(0); -}; - -// I wonder if this should use the constructor style like Body... -var createStaticBody = function() -{ - var body = new Body(Infinity, Infinity); - body.nodeIdleTime = Infinity; - - return body; -}; - cp.StaticBody = createStaticBody; - -if (typeof DEBUG !== 'undefined' && DEBUG) { - var v_assert_nan = function(v, message){assert(v.x == v.x && v.y == v.y, message); }; - var v_assert_infinite = function(v, message){assert(Math.abs(v.x) !== Infinity && Math.abs(v.y) !== Infinity, message);}; - var v_assert_sane = function(v, message){v_assert_nan(v, message); v_assert_infinite(v, message);}; - - Body.prototype.sanityCheck = function() - { - assert(this.m === this.m && this.m_inv === this.m_inv, "Body's mass is invalid."); - assert(this.i === this.i && this.i_inv === this.i_inv, "Body's moment is invalid."); - - v_assert_sane(this.p, "Body's position is invalid."); - v_assert_sane(this.f, "Body's force is invalid."); - assert(this.vx === this.vx && Math.abs(this.vx) !== Infinity, "Body's velocity is invalid."); - assert(this.vy === this.vy && Math.abs(this.vy) !== Infinity, "Body's velocity is invalid."); - - assert(this.a === this.a && Math.abs(this.a) !== Infinity, "Body's angle is invalid."); - assert(this.w === this.w && Math.abs(this.w) !== Infinity, "Body's angular velocity is invalid."); - assert(this.t === this.t && Math.abs(this.t) !== Infinity, "Body's torque is invalid."); - - v_assert_sane(this.rot, "Body's rotation vector is invalid."); - - assert(this.v_limit === this.v_limit, "Body's velocity limit is invalid."); - assert(this.w_limit === this.w_limit, "Body's angular velocity limit is invalid."); - }; -} else { - Body.prototype.sanityCheck = function(){}; -} - -Body.prototype.getPos = function() { return this.p; }; -Body.prototype.getVel = function() { return new Vect(this.vx, this.vy); }; -Body.prototype.getAngVel = function() { return this.w; }; - -/// Returns true if the body is sleeping. -Body.prototype.isSleeping = function() -{ - return this.nodeRoot !== null; -}; - -/// Returns true if the body is static. -Body.prototype.isStatic = function() -{ - return this.nodeIdleTime === Infinity; -}; - -/// Returns true if the body has not been added to a space. -Body.prototype.isRogue = function() -{ - return this.space === null; -}; - -// It would be nicer to use defineProperty for this, but its about 30x slower: -// http://jsperf.com/defineproperty-vs-setter -Body.prototype.setMass = function(mass) -{ - assert(mass > 0, "Mass must be positive and non-zero."); - - //activate is defined in cpSpaceComponent - this.activate(); - this.m = mass; - this.m_inv = 1/mass; -}; - -Body.prototype.setMoment = function(moment) -{ - assert(moment > 0, "Moment of Inertia must be positive and non-zero."); - - this.activate(); - this.i = moment; - this.i_inv = 1/moment; -}; - -Body.prototype.addShape = function(shape) -{ - this.shapeList.push(shape); -}; - -Body.prototype.removeShape = function(shape) -{ - // This implementation has a linear time complexity with the number of shapes. - // The original implementation used linked lists instead, which might be faster if - // you're constantly editing the shape of a body. I expect most bodies will never - // have their shape edited, so I'm just going to use the simplest possible implemention. - deleteObjFromList(this.shapeList, shape); -}; - -var filterConstraints = function(node, body, filter) -{ - if(node === filter){ - return node.next(body); - } else if(node.a === body){ - node.next_a = filterConstraints(node.next_a, body, filter); - } else { - node.next_b = filterConstraints(node.next_b, body, filter); - } - - return node; -}; - -Body.prototype.removeConstraint = function(constraint) -{ - // The constraint must be in the constraints list when this is called. - this.constraintList = filterConstraints(this.constraintList, this, constraint); -}; - -Body.prototype.setPos = function(pos) -{ - this.activate(); - this.sanityCheck(); - // If I allow the position to be set to vzero, vzero will get changed. - if (pos === vzero) { - pos = cp.v(0,0); - } - this.p = pos; -}; - -Body.prototype.setVel = function(velocity) -{ - this.activate(); - this.vx = velocity.x; - this.vy = velocity.y; -}; - -Body.prototype.setAngVel = function(w) -{ - this.activate(); - this.w = w; -}; - -Body.prototype.setAngleInternal = function(angle) -{ - assert(!isNaN(angle), "Internal Error: Attempting to set body's angle to NaN"); - this.a = angle;//fmod(a, (cpFloat)M_PI*2.0f); - - //this.rot = vforangle(angle); - this.rot.x = Math.cos(angle); - this.rot.y = Math.sin(angle); -}; - -Body.prototype.setAngle = function(angle) -{ - this.activate(); - this.sanityCheck(); - this.setAngleInternal(angle); -}; - -Body.prototype.velocity_func = function(gravity, damping, dt) -{ - //this.v = vclamp(vadd(vmult(this.v, damping), vmult(vadd(gravity, vmult(this.f, this.m_inv)), dt)), this.v_limit); - var vx = this.vx * damping + (gravity.x + this.f.x * this.m_inv) * dt; - var vy = this.vy * damping + (gravity.y + this.f.y * this.m_inv) * dt; - - //var v = vclamp(new Vect(vx, vy), this.v_limit); - //this.vx = v.x; this.vy = v.y; - var v_limit = this.v_limit; - var lensq = vx * vx + vy * vy; - var scale = (lensq > v_limit*v_limit) ? v_limit / Math.sqrt(lensq) : 1; - this.vx = vx * scale; - this.vy = vy * scale; - - var w_limit = this.w_limit; - this.w = clamp(this.w*damping + this.t*this.i_inv*dt, -w_limit, w_limit); - - this.sanityCheck(); -}; - -Body.prototype.position_func = function(dt) -{ - //this.p = vadd(this.p, vmult(vadd(this.v, this.v_bias), dt)); - - //this.p = this.p + (this.v + this.v_bias) * dt; - this.p.x += (this.vx + this.v_biasx) * dt; - this.p.y += (this.vy + this.v_biasy) * dt; - - this.setAngleInternal(this.a + (this.w + this.w_bias)*dt); - - this.v_biasx = this.v_biasy = 0; - this.w_bias = 0; - - this.sanityCheck(); -}; - -Body.prototype.resetForces = function() -{ - this.activate(); - this.f = new Vect(0,0); - this.t = 0; -}; - -Body.prototype.applyForce = function(force, r) -{ - this.activate(); - this.f = vadd(this.f, force); - this.t += vcross(r, force); -}; - -Body.prototype.applyImpulse = function(j, r) -{ - this.activate(); - apply_impulse(this, j.x, j.y, r); -}; - -Body.prototype.getVelAtPoint = function(r) -{ - return vadd(new Vect(this.vx, this.vy), vmult(vperp(r), this.w)); -}; - -/// Get the velocity on a body (in world units) at a point on the body in world coordinates. -Body.prototype.getVelAtWorldPoint = function(point) -{ - return this.getVelAtPoint(vsub(point, this.p)); -}; - -/// Get the velocity on a body (in world units) at a point on the body in local coordinates. -Body.prototype.getVelAtLocalPoint = function(point) -{ - return this.getVelAtPoint(vrotate(point, this.rot)); -}; - -Body.prototype.eachShape = function(func) -{ - for(var i = 0, len = this.shapeList.length; i < len; i++) { - func(this.shapeList[i]); - } -}; - -Body.prototype.eachConstraint = function(func) -{ - var constraint = this.constraintList; - while(constraint) { - var next = constraint.next(this); - func(constraint); - constraint = next; - } -}; - -Body.prototype.eachArbiter = function(func) -{ - var arb = this.arbiterList; - while(arb){ - var next = arb.next(this); - - arb.swappedColl = (this === arb.body_b); - func(arb); - - arb = next; - } -}; - -/// Convert body relative/local coordinates to absolute/world coordinates. -Body.prototype.local2World = function(v) -{ - return vadd(this.p, vrotate(v, this.rot)); -}; - -/// Convert body absolute/world coordinates to relative/local coordinates. -Body.prototype.world2Local = function(v) -{ - return vunrotate(vsub(v, this.p), this.rot); -}; - -/// Get the kinetic energy of a body. -Body.prototype.kineticEnergy = function() -{ - // Need to do some fudging to avoid NaNs - var vsq = this.vx*this.vx + this.vy*this.vy; - var wsq = this.w * this.w; - return (vsq ? vsq*this.m : 0) + (wsq ? wsq*this.i : 0); -}; - -/* Copyright (c) 2010 Scott Lembcke - * - * 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. - */ - -/** - @defgroup cpSpatialIndex cpSpatialIndex - - Spatial indexes are data structures that are used to accelerate collision detection - and spatial queries. Chipmunk provides a number of spatial index algorithms to pick from - and they are programmed in a generic way so that you can use them for holding more than - just Shapes. - - It works by using pointers to the objects you add and using a callback to ask your code - for bounding boxes when it needs them. Several types of queries can be performed an index as well - as reindexing and full collision information. All communication to the spatial indexes is performed - through callback functions. - - Spatial indexes should be treated as opaque structs. - This means you shouldn't be reading any of the fields directly. - - All spatial indexes define the following methods: - - // The number of objects in the spatial index. - count = 0; - - // Iterate the objects in the spatial index. @c func will be called once for each object. - each(func); - - // Returns true if the spatial index contains the given object. - // Most spatial indexes use hashed storage, so you must provide a hash value too. - contains(obj, hashid); - - // Add an object to a spatial index. - insert(obj, hashid); - - // Remove an object from a spatial index. - remove(obj, hashid); - - // Perform a full reindex of a spatial index. - reindex(); - - // Reindex a single object in the spatial index. - reindexObject(obj, hashid); - - // Perform a point query against the spatial index, calling @c func for each potential match. - // A pointer to the point will be passed as @c obj1 of @c func. - // func(shape); - pointQuery(point, func); - - // Perform a segment query against the spatial index, calling @c func for each potential match. - // func(shape); - segmentQuery(vect a, vect b, t_exit, func); - - // Perform a rectangle query against the spatial index, calling @c func for each potential match. - // func(shape); - query(bb, func); - - // Simultaneously reindex and find all colliding objects. - // @c func will be called once for each potentially overlapping pair of objects found. - // If the spatial index was initialized with a static index, it will collide it's objects against that as well. - reindexQuery(func); -*/ - -var SpatialIndex = cp.SpatialIndex = function(staticIndex) -{ - this.staticIndex = staticIndex; - - - if(staticIndex){ - if(staticIndex.dynamicIndex){ - throw new Error("This static index is already associated with a dynamic index."); - } - staticIndex.dynamicIndex = this; - } -}; - -// Collide the objects in an index against the objects in a staticIndex using the query callback function. -SpatialIndex.prototype.collideStatic = function(staticIndex, func) -{ - if(staticIndex.count > 0){ - var query = staticIndex.query; - - this.each(function(obj) { - query(obj, new BB(obj.bb_l, obj.bb_b, obj.bb_r, obj.bb_t), func); - }); - } -}; - - -/* Copyright (c) 2009 Scott Lembcke - * - * 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. - */ - -// This file implements a modified AABB tree for collision detection. - -var BBTree = cp.BBTree = function(staticIndex) -{ - SpatialIndex.call(this, staticIndex); - - this.velocityFunc = null; - - // This is a hash from object ID -> object for the objects stored in the BBTree. - this.leaves = {}; - // A count of the number of leaves in the BBTree. - this.count = 0; - - this.root = null; - - // A linked list containing an object pool of tree nodes and pairs. - this.pooledNodes = null; - this.pooledPairs = null; - - this.stamp = 0; -}; - -BBTree.prototype = Object.create(SpatialIndex.prototype); - -var numNodes = 0; - -var Node = function(tree, a, b) -{ - this.obj = null; - this.bb_l = min(a.bb_l, b.bb_l); - this.bb_b = min(a.bb_b, b.bb_b); - this.bb_r = max(a.bb_r, b.bb_r); - this.bb_t = max(a.bb_t, b.bb_t); - this.parent = null; - - this.setA(a); - this.setB(b); -}; - -BBTree.prototype.makeNode = function(a, b) -{ - var node = this.pooledNodes; - if(node){ - this.pooledNodes = node.parent; - node.constructor(this, a, b); - return node; - } else { - numNodes++; - return new Node(this, a, b); - } -}; - -var numLeaves = 0; -var Leaf = function(tree, obj) -{ - this.obj = obj; - tree.getBB(obj, this); - - this.parent = null; - - this.stamp = 1; - this.pairs = null; - numLeaves++; -}; - -// **** Misc Functions - -BBTree.prototype.getBB = function(obj, dest) -{ - var velocityFunc = this.velocityFunc; - if(velocityFunc){ - var coef = 0.1; - var x = (obj.bb_r - obj.bb_l)*coef; - var y = (obj.bb_t - obj.bb_b)*coef; - - var v = vmult(velocityFunc(obj), 0.1); - - dest.bb_l = obj.bb_l + min(-x, v.x); - dest.bb_b = obj.bb_b + min(-y, v.y); - dest.bb_r = obj.bb_r + max( x, v.x); - dest.bb_t = obj.bb_t + max( y, v.y); - } else { - dest.bb_l = obj.bb_l; - dest.bb_b = obj.bb_b; - dest.bb_r = obj.bb_r; - dest.bb_t = obj.bb_t; - } -}; - -BBTree.prototype.getStamp = function() -{ - var dynamic = this.dynamicIndex; - return (dynamic && dynamic.stamp ? dynamic.stamp : this.stamp); -}; - -BBTree.prototype.incrementStamp = function() -{ - if(this.dynamicIndex && this.dynamicIndex.stamp){ - this.dynamicIndex.stamp++; - } else { - this.stamp++; - } -} - -// **** Pair/Thread Functions - -var numPairs = 0; -// Objects created with constructors are faster than object literals. :( -var Pair = function(leafA, nextA, leafB, nextB) -{ - this.prevA = null; - this.leafA = leafA; - this.nextA = nextA; - - this.prevB = null; - this.leafB = leafB; - this.nextB = nextB; -}; - -BBTree.prototype.makePair = function(leafA, nextA, leafB, nextB) -{ - //return new Pair(leafA, nextA, leafB, nextB); - var pair = this.pooledPairs; - if (pair) - { - this.pooledPairs = pair.prevA; - - pair.prevA = null; - pair.leafA = leafA; - pair.nextA = nextA; - - pair.prevB = null; - pair.leafB = leafB; - pair.nextB = nextB; - - //pair.constructor(leafA, nextA, leafB, nextB); - return pair; - } else { - numPairs++; - return new Pair(leafA, nextA, leafB, nextB); - } -}; - -Pair.prototype.recycle = function(tree) -{ - this.prevA = tree.pooledPairs; - tree.pooledPairs = this; -}; - -var unlinkThread = function(prev, leaf, next) -{ - if(next){ - if(next.leafA === leaf) next.prevA = prev; else next.prevB = prev; - } - - if(prev){ - if(prev.leafA === leaf) prev.nextA = next; else prev.nextB = next; - } else { - leaf.pairs = next; - } -}; - -Leaf.prototype.clearPairs = function(tree) -{ - var pair = this.pairs, - next; - - this.pairs = null; - - while(pair){ - if(pair.leafA === this){ - next = pair.nextA; - unlinkThread(pair.prevB, pair.leafB, pair.nextB); - } else { - next = pair.nextB; - unlinkThread(pair.prevA, pair.leafA, pair.nextA); - } - pair.recycle(tree); - pair = next; - } -}; - -var pairInsert = function(a, b, tree) -{ - var nextA = a.pairs, nextB = b.pairs; - var pair = tree.makePair(a, nextA, b, nextB); - a.pairs = b.pairs = pair; - - if(nextA){ - if(nextA.leafA === a) nextA.prevA = pair; else nextA.prevB = pair; - } - - if(nextB){ - if(nextB.leafA === b) nextB.prevA = pair; else nextB.prevB = pair; - } -}; - -// **** Node Functions - -Node.prototype.recycle = function(tree) -{ - this.parent = tree.pooledNodes; - tree.pooledNodes = this; -}; - -Leaf.prototype.recycle = function(tree) -{ - // Its not worth the overhead to recycle leaves. -}; - -Node.prototype.setA = function(value) -{ - this.A = value; - value.parent = this; -}; - -Node.prototype.setB = function(value) -{ - this.B = value; - value.parent = this; -}; - -Leaf.prototype.isLeaf = true; -Node.prototype.isLeaf = false; - -Node.prototype.otherChild = function(child) -{ - return (this.A == child ? this.B : this.A); -}; - -Node.prototype.replaceChild = function(child, value, tree) -{ - assertSoft(child == this.A || child == this.B, "Node is not a child of parent."); - - if(this.A == child){ - this.A.recycle(tree); - this.setA(value); - } else { - this.B.recycle(tree); - this.setB(value); - } - - for(var node=this; node; node = node.parent){ - //node.bb = bbMerge(node.A.bb, node.B.bb); - var a = node.A; - var b = node.B; - node.bb_l = min(a.bb_l, b.bb_l); - node.bb_b = min(a.bb_b, b.bb_b); - node.bb_r = max(a.bb_r, b.bb_r); - node.bb_t = max(a.bb_t, b.bb_t); - } -}; - -Node.prototype.bbArea = Leaf.prototype.bbArea = function() -{ - return (this.bb_r - this.bb_l)*(this.bb_t - this.bb_b); -}; - -var bbTreeMergedArea = function(a, b) -{ - return (max(a.bb_r, b.bb_r) - min(a.bb_l, b.bb_l))*(max(a.bb_t, b.bb_t) - min(a.bb_b, b.bb_b)); -}; - -// **** Subtree Functions - -// Would it be better to make these functions instance methods on Node and Leaf? - -var bbProximity = function(a, b) -{ - return Math.abs(a.bb_l + a.bb_r - b.bb_l - b.bb_r) + Math.abs(a.bb_b + a.bb_t - b.bb_b - b.bb_t); -}; - -var subtreeInsert = function(subtree, leaf, tree) -{ -// var s = new Error().stack; -// traces[s] = traces[s] ? traces[s]+1 : 1; - - if(subtree == null){ - return leaf; - } else if(subtree.isLeaf){ - return tree.makeNode(leaf, subtree); - } else { - var cost_a = subtree.B.bbArea() + bbTreeMergedArea(subtree.A, leaf); - var cost_b = subtree.A.bbArea() + bbTreeMergedArea(subtree.B, leaf); - - if(cost_a === cost_b){ - cost_a = bbProximity(subtree.A, leaf); - cost_b = bbProximity(subtree.B, leaf); - } - - if(cost_b < cost_a){ - subtree.setB(subtreeInsert(subtree.B, leaf, tree)); - } else { - subtree.setA(subtreeInsert(subtree.A, leaf, tree)); - } - -// subtree.bb = bbMerge(subtree.bb, leaf.bb); - subtree.bb_l = min(subtree.bb_l, leaf.bb_l); - subtree.bb_b = min(subtree.bb_b, leaf.bb_b); - subtree.bb_r = max(subtree.bb_r, leaf.bb_r); - subtree.bb_t = max(subtree.bb_t, leaf.bb_t); - - return subtree; - } -}; - -Node.prototype.intersectsBB = Leaf.prototype.intersectsBB = function(bb) -{ - return (this.bb_l <= bb.r && bb.l <= this.bb_r && this.bb_b <= bb.t && bb.b <= this.bb_t); -}; - -var subtreeQuery = function(subtree, bb, func) -{ - //if(bbIntersectsBB(subtree.bb, bb)){ - if(subtree.intersectsBB(bb)){ - if(subtree.isLeaf){ - func(subtree.obj); - } else { - subtreeQuery(subtree.A, bb, func); - subtreeQuery(subtree.B, bb, func); - } - } -}; - -/// Returns the fraction along the segment query the node hits. Returns Infinity if it doesn't hit. -var nodeSegmentQuery = function(node, a, b) -{ - var idx = 1/(b.x - a.x); - var tx1 = (node.bb_l == a.x ? -Infinity : (node.bb_l - a.x)*idx); - var tx2 = (node.bb_r == a.x ? Infinity : (node.bb_r - a.x)*idx); - var txmin = min(tx1, tx2); - var txmax = max(tx1, tx2); - - var idy = 1/(b.y - a.y); - var ty1 = (node.bb_b == a.y ? -Infinity : (node.bb_b - a.y)*idy); - var ty2 = (node.bb_t == a.y ? Infinity : (node.bb_t - a.y)*idy); - var tymin = min(ty1, ty2); - var tymax = max(ty1, ty2); - - if(tymin <= txmax && txmin <= tymax){ - var min_ = max(txmin, tymin); - var max_ = min(txmax, tymax); - - if(0.0 <= max_ && min_ <= 1.0) return max(min_, 0.0); - } - - return Infinity; -}; - -var subtreeSegmentQuery = function(subtree, a, b, t_exit, func) -{ - if(subtree.isLeaf){ - return func(subtree.obj); - } else { - var t_a = nodeSegmentQuery(subtree.A, a, b); - var t_b = nodeSegmentQuery(subtree.B, a, b); - - if(t_a < t_b){ - if(t_a < t_exit) t_exit = min(t_exit, subtreeSegmentQuery(subtree.A, a, b, t_exit, func)); - if(t_b < t_exit) t_exit = min(t_exit, subtreeSegmentQuery(subtree.B, a, b, t_exit, func)); - } else { - if(t_b < t_exit) t_exit = min(t_exit, subtreeSegmentQuery(subtree.B, a, b, t_exit, func)); - if(t_a < t_exit) t_exit = min(t_exit, subtreeSegmentQuery(subtree.A, a, b, t_exit, func)); - } - - return t_exit; - } -}; - -BBTree.prototype.subtreeRecycle = function(node) -{ - if(node.isLeaf){ - this.subtreeRecycle(node.A); - this.subtreeRecycle(node.B); - node.recycle(this); - } -}; - -var subtreeRemove = function(subtree, leaf, tree) -{ - if(leaf == subtree){ - return null; - } else { - var parent = leaf.parent; - if(parent == subtree){ - var other = subtree.otherChild(leaf); - other.parent = subtree.parent; - subtree.recycle(tree); - return other; - } else { - parent.parent.replaceChild(parent, parent.otherChild(leaf), tree); - return subtree; - } - } -}; - -// **** Marking Functions - -/* -typedef struct MarkContext { - bbTree *tree; - Node *staticRoot; - cpSpatialIndexQueryFunc func; -} MarkContext; -*/ - -var bbTreeIntersectsNode = function(a, b) -{ - return (a.bb_l <= b.bb_r && b.bb_l <= a.bb_r && a.bb_b <= b.bb_t && b.bb_b <= a.bb_t); -}; - -Leaf.prototype.markLeafQuery = function(leaf, left, tree, func) -{ - if(bbTreeIntersectsNode(leaf, this)){ - if(left){ - pairInsert(leaf, this, tree); - } else { - if(this.stamp < leaf.stamp) pairInsert(this, leaf, tree); - if(func) func(leaf.obj, this.obj); - } - } -}; - -Node.prototype.markLeafQuery = function(leaf, left, tree, func) -{ - if(bbTreeIntersectsNode(leaf, this)){ - this.A.markLeafQuery(leaf, left, tree, func); - this.B.markLeafQuery(leaf, left, tree, func); - } -}; - -Leaf.prototype.markSubtree = function(tree, staticRoot, func) -{ - if(this.stamp == tree.getStamp()){ - if(staticRoot) staticRoot.markLeafQuery(this, false, tree, func); - - for(var node = this; node.parent; node = node.parent){ - if(node == node.parent.A){ - node.parent.B.markLeafQuery(this, true, tree, func); - } else { - node.parent.A.markLeafQuery(this, false, tree, func); - } - } - } else { - var pair = this.pairs; - while(pair){ - if(this === pair.leafB){ - if(func) func(pair.leafA.obj, this.obj); - pair = pair.nextB; - } else { - pair = pair.nextA; - } - } - } -}; - -Node.prototype.markSubtree = function(tree, staticRoot, func) -{ - this.A.markSubtree(tree, staticRoot, func); - this.B.markSubtree(tree, staticRoot, func); -}; - -// **** Leaf Functions - -Leaf.prototype.containsObj = function(obj) -{ - return (this.bb_l <= obj.bb_l && this.bb_r >= obj.bb_r && this.bb_b <= obj.bb_b && this.bb_t >= obj.bb_t); -}; - -Leaf.prototype.update = function(tree) -{ - var root = tree.root; - var obj = this.obj; - - //if(!bbContainsBB(this.bb, bb)){ - if(!this.containsObj(obj)){ - tree.getBB(this.obj, this); - - root = subtreeRemove(root, this, tree); - tree.root = subtreeInsert(root, this, tree); - - this.clearPairs(tree); - this.stamp = tree.getStamp(); - - return true; - } - - return false; -}; - -Leaf.prototype.addPairs = function(tree) -{ - var dynamicIndex = tree.dynamicIndex; - if(dynamicIndex){ - var dynamicRoot = dynamicIndex.root; - if(dynamicRoot){ - dynamicRoot.markLeafQuery(this, true, dynamicIndex, null); - } - } else { - var staticRoot = tree.staticIndex.root; - this.markSubtree(tree, staticRoot, null); - } -}; - -// **** Insert/Remove - -BBTree.prototype.insert = function(obj, hashid) -{ - var leaf = new Leaf(this, obj); - - this.leaves[hashid] = leaf; - this.root = subtreeInsert(this.root, leaf, this); - this.count++; - - leaf.stamp = this.getStamp(); - leaf.addPairs(this); - this.incrementStamp(); -}; - -BBTree.prototype.remove = function(obj, hashid) -{ - var leaf = this.leaves[hashid]; - - delete this.leaves[hashid]; - this.root = subtreeRemove(this.root, leaf, this); - this.count--; - - leaf.clearPairs(this); - leaf.recycle(this); -}; - -BBTree.prototype.contains = function(obj, hashid) -{ - return this.leaves[hashid] != null; -}; - -// **** Reindex -var voidQueryFunc = function(obj1, obj2){}; - -BBTree.prototype.reindexQuery = function(func) -{ - if(!this.root) return; - - // LeafUpdate() may modify this.root. Don't cache it. - var hashid, - leaves = this.leaves; - for (hashid in leaves) - { - leaves[hashid].update(this); - } - - var staticIndex = this.staticIndex; - var staticRoot = staticIndex && staticIndex.root; - - this.root.markSubtree(this, staticRoot, func); - if(staticIndex && !staticRoot) this.collideStatic(this, staticIndex, func); - - this.incrementStamp(); -}; - -BBTree.prototype.reindex = function() -{ - this.reindexQuery(voidQueryFunc); -}; - -BBTree.prototype.reindexObject = function(obj, hashid) -{ - var leaf = this.leaves[hashid]; - if(leaf){ - if(leaf.update(this)) leaf.addPairs(this); - this.incrementStamp(); - } -}; - -// **** Query - -// This has since been removed from upstream Chipmunk - which recommends you just use query() below -// directly. -BBTree.prototype.pointQuery = function(point, func) -{ - this.query(new BB(point.x, point.y, point.x, point.y), func); -}; - -BBTree.prototype.segmentQuery = function(a, b, t_exit, func) -{ - if(this.root) subtreeSegmentQuery(this.root, a, b, t_exit, func); -}; - -BBTree.prototype.query = function(bb, func) -{ - if(this.root) subtreeQuery(this.root, bb, func); -}; - -// **** Misc - -BBTree.prototype.count = function() -{ - return this.count; -}; - -BBTree.prototype.each = function(func) -{ - var hashid; - for(hashid in this.leaves) - { - func(this.leaves[hashid].obj); - } -}; - -// **** Tree Optimization - -var bbTreeMergedArea2 = function(node, l, b, r, t) -{ - return (max(node.bb_r, r) - min(node.bb_l, l))*(max(node.bb_t, t) - min(node.bb_b, b)); -}; - -var partitionNodes = function(tree, nodes, offset, count) -{ - if(count == 1){ - return nodes[offset]; - } else if(count == 2) { - return tree.makeNode(nodes[offset], nodes[offset + 1]); - } - - // Find the AABB for these nodes - //var bb = nodes[offset].bb; - var node = nodes[offset]; - var bb_l = node.bb_l, - bb_b = node.bb_b, - bb_r = node.bb_r, - bb_t = node.bb_t; - - var end = offset + count; - for(var i=offset + 1; i bb_t - bb_b); - - // Sort the bounds and use the median as the splitting point - var bounds = new Array(count*2); - if(splitWidth){ - for(var i=offset; inext = next; - if(prev.body_a === body) { - prev.thread_a_next = next; - } else { - prev.thread_b_next = next; - } - } else { - body.arbiterList = next; - } - - if(next){ - // cpArbiterThreadForBody(next, body)->prev = prev; - if(next.body_a === body){ - next.thread_a_prev = prev; - } else { - next.thread_b_prev = prev; - } - } -}; - -Arbiter.prototype.unthread = function() -{ - unthreadHelper(this, this.body_a, this.thread_a_prev, this.thread_a_next); - unthreadHelper(this, this.body_b, this.thread_b_prev, this.thread_b_next); - this.thread_a_prev = this.thread_a_next = null; - this.thread_b_prev = this.thread_b_next = null; -}; - -//cpFloat -//cpContactsEstimateCrushingImpulse(cpContact *contacts, int numContacts) -//{ -// cpFloat fsum = 0; -// cpVect vsum = vzero; -// -// for(int i=0; i= mindist*mindist) return; - - var dist = Math.sqrt(distsq); - - // Allocate and initialize the contact. - return new Contact( - vadd(p1, vmult(delta, 0.5 + (r1 - 0.5*mindist)/(dist ? dist : Infinity))), - (dist ? vmult(delta, 1/dist) : new Vect(1, 0)), - dist - mindist, - 0 - ); -}; - -// Collide circle shapes. -var circle2circle = function(circ1, circ2) -{ - var contact = circle2circleQuery(circ1.tc, circ2.tc, circ1.r, circ2.r); - return contact ? [contact] : NONE; -}; - -var circle2segment = function(circleShape, segmentShape) -{ - var seg_a = segmentShape.ta; - var seg_b = segmentShape.tb; - var center = circleShape.tc; - - var seg_delta = vsub(seg_b, seg_a); - var closest_t = clamp01(vdot(seg_delta, vsub(center, seg_a))/vlengthsq(seg_delta)); - var closest = vadd(seg_a, vmult(seg_delta, closest_t)); - - var contact = circle2circleQuery(center, closest, circleShape.r, segmentShape.r); - if(contact){ - var n = contact.n; - - // Reject endcap collisions if tangents are provided. - return ( - (closest_t === 0 && vdot(n, segmentShape.a_tangent) < 0) || - (closest_t === 1 && vdot(n, segmentShape.b_tangent) < 0) - ) ? NONE : [contact]; - } else { - return NONE; - } -} - -// Find the minimum separating axis for the given poly and axis list. -// -// This function needs to return two values - the index of the min. separating axis and -// the value itself. Short of inlining MSA, returning values through a global like this -// is the fastest implementation. -// -// See: http://jsperf.com/return-two-values-from-function/2 -var last_MSA_min = 0; -var findMSA = function(poly, planes) -{ - var min_index = 0; - var min = poly.valueOnAxis(planes[0].n, planes[0].d); - if(min > 0) return -1; - - for(var i=1; i 0) { - return -1; - } else if(dist > min){ - min = dist; - min_index = i; - } - } - - last_MSA_min = min; - return min_index; -}; - -// Add contacts for probably penetrating vertexes. -// This handles the degenerate case where an overlap was detected, but no vertexes fall inside -// the opposing polygon. (like a star of david) -var findVertsFallback = function(poly1, poly2, n, dist) -{ - var arr = []; - - var verts1 = poly1.tVerts; - for(var i=0; i>1))); - } - } - - var verts2 = poly2.tVerts; - for(var i=0; i>1))); - } - } - - return (arr.length ? arr : findVertsFallback(poly1, poly2, n, dist)); -}; - -// Collide poly shapes together. -var poly2poly = function(poly1, poly2) -{ - var mini1 = findMSA(poly2, poly1.tPlanes); - if(mini1 == -1) return NONE; - var min1 = last_MSA_min; - - var mini2 = findMSA(poly1, poly2.tPlanes); - if(mini2 == -1) return NONE; - var min2 = last_MSA_min; - - // There is overlap, find the penetrating verts - if(min1 > min2) - return findVerts(poly1, poly2, poly1.tPlanes[mini1].n, min1); - else - return findVerts(poly1, poly2, vneg(poly2.tPlanes[mini2].n), min2); -}; - -// Like cpPolyValueOnAxis(), but for segments. -var segValueOnAxis = function(seg, n, d) -{ - var a = vdot(n, seg.ta) - seg.r; - var b = vdot(n, seg.tb) - seg.r; - return min(a, b) - d; -}; - -// Identify vertexes that have penetrated the segment. -var findPointsBehindSeg = function(arr, seg, poly, pDist, coef) -{ - var dta = vcross(seg.tn, seg.ta); - var dtb = vcross(seg.tn, seg.tb); - var n = vmult(seg.tn, coef); - - var verts = poly.tVerts; - for(var i=0; i= dt && dt >= dtb){ - arr.push(new Contact(new Vect(vx, vy), n, pDist, hashPair(poly.hashid, i))); - } - } - } -}; - -// This one is complicated and gross. Just don't go there... -// TODO: Comment me! -var seg2poly = function(seg, poly) -{ - var arr = []; - - var planes = poly.tPlanes; - var numVerts = planes.length; - - var segD = vdot(seg.tn, seg.ta); - var minNorm = poly.valueOnAxis(seg.tn, segD) - seg.r; - var minNeg = poly.valueOnAxis(vneg(seg.tn), -segD) - seg.r; - if(minNeg > 0 || minNorm > 0) return NONE; - - var mini = 0; - var poly_min = segValueOnAxis(seg, planes[0].n, planes[0].d); - if(poly_min > 0) return NONE; - for(var i=0; i 0){ - return NONE; - } else if(dist > poly_min){ - poly_min = dist; - mini = i; - } - } - - var poly_n = vneg(planes[mini].n); - - var va = vadd(seg.ta, vmult(poly_n, seg.r)); - var vb = vadd(seg.tb, vmult(poly_n, seg.r)); - if(poly.containsVert(va.x, va.y)) - arr.push(new Contact(va, poly_n, poly_min, hashPair(seg.hashid, 0))); - if(poly.containsVert(vb.x, vb.y)) - arr.push(new Contact(vb, poly_n, poly_min, hashPair(seg.hashid, 1))); - - // Floating point precision problems here. - // This will have to do for now. -// poly_min -= cp_collision_slop; // TODO is this needed anymore? - - if(minNorm >= poly_min || minNeg >= poly_min) { - if(minNorm > minNeg) - findPointsBehindSeg(arr, seg, poly, minNorm, 1); - else - findPointsBehindSeg(arr, seg, poly, minNeg, -1); - } - - // If no other collision points are found, try colliding endpoints. - if(arr.length === 0){ - var mini2 = mini * 2; - var verts = poly.tVerts; - - var poly_a = new Vect(verts[mini2], verts[mini2+1]); - - var con; - if((con = circle2circleQuery(seg.ta, poly_a, seg.r, 0, arr))) return [con]; - if((con = circle2circleQuery(seg.tb, poly_a, seg.r, 0, arr))) return [con]; - - var len = numVerts * 2; - var poly_b = new Vect(verts[(mini2+2)%len], verts[(mini2+3)%len]); - if((con = circle2circleQuery(seg.ta, poly_b, seg.r, 0, arr))) return [con]; - if((con = circle2circleQuery(seg.tb, poly_b, seg.r, 0, arr))) return [con]; - } - -// console.log(poly.tVerts, poly.tPlanes); -// console.log('seg2poly', arr); - return arr; -}; - -// This one is less gross, but still gross. -// TODO: Comment me! -var circle2poly = function(circ, poly) -{ - var planes = poly.tPlanes; - - var mini = 0; - var min = vdot(planes[0].n, circ.tc) - planes[0].d - circ.r; - for(var i=0; i 0){ - return NONE; - } else if(dist > min) { - min = dist; - mini = i; - } - } - - var n = planes[mini].n; - - var verts = poly.tVerts; - var len = verts.length; - var mini2 = mini<<1; - - //var a = poly.tVerts[mini]; - //var b = poly.tVerts[(mini + 1)%poly.tVerts.length]; - var ax = verts[mini2]; - var ay = verts[mini2+1]; - var bx = verts[(mini2+2)%len]; - var by = verts[(mini2+3)%len]; - - var dta = vcross2(n.x, n.y, ax, ay); - var dtb = vcross2(n.x, n.y, bx, by); - var dt = vcross(n, circ.tc); - - if(dt < dtb){ - var con = circle2circleQuery(circ.tc, new Vect(bx, by), circ.r, 0, con); - return con ? [con] : NONE; - } else if(dt < dta) { - return [new Contact( - vsub(circ.tc, vmult(n, circ.r + min/2)), - vneg(n), - min, - 0 - )]; - } else { - var con = circle2circleQuery(circ.tc, new Vect(ax, ay), circ.r, 0, con); - return con ? [con] : NONE; - } -}; - -// The javascripty way to do this would be either nested object or methods on the prototypes. -// -// However, the *fastest* way is the method below. -// See: http://jsperf.com/dispatch - -// These are copied from the prototypes into the actual objects in the Shape constructor. -CircleShape.prototype.collisionCode = 0; -SegmentShape.prototype.collisionCode = 1; -PolyShape.prototype.collisionCode = 2; - -CircleShape.prototype.collisionTable = [ - circle2circle, - circle2segment, - circle2poly -]; - -SegmentShape.prototype.collisionTable = [ - null, - function(segA, segB) { return NONE; }, // seg2seg - seg2poly -]; - -PolyShape.prototype.collisionTable = [ - null, - null, - poly2poly -]; - -var collideShapes = cp.collideShapes = function(a, b) -{ - assert(a.collisionCode <= b.collisionCode, 'Collided shapes must be sorted by type'); - return a.collisionTable[b.collisionCode](a, b); -}; - -/* Copyright (c) 2007 Scott Lembcke - * - * 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 defaultCollisionHandler = new CollisionHandler(); - -/// Basic Unit of Simulation in Chipmunk -var Space = cp.Space = function() { - this.stamp = 0; - this.curr_dt = 0; - - this.bodies = []; - this.rousedBodies = []; - this.sleepingComponents = []; - - this.staticShapes = new BBTree(null); - this.activeShapes = new BBTree(this.staticShapes); - - this.arbiters = []; - this.contactBuffersHead = null; - this.cachedArbiters = {}; - //this.pooledArbiters = []; - - this.constraints = []; - - this.locked = 0; - - this.collisionHandlers = {}; - this.defaultHandler = defaultCollisionHandler; - - this.postStepCallbacks = []; - - /// Number of iterations to use in the impulse solver to solve contacts. - this.iterations = 10; - - /// Gravity to pass to rigid bodies when integrating velocity. - this.gravity = vzero; - - /// Damping rate expressed as the fraction of velocity bodies retain each second. - /// A value of 0.9 would mean that each body's velocity will drop 10% per second. - /// The default value is 1.0, meaning no damping is applied. - /// @note This damping value is different than those of cpDampedSpring and cpDampedRotarySpring. - this.damping = 1; - - /// Speed threshold for a body to be considered idle. - /// The default value of 0 means to let the space guess a good threshold based on gravity. - this.idleSpeedThreshold = 0; - - /// Time a group of bodies must remain idle in order to fall asleep. - /// Enabling sleeping also implicitly enables the the contact graph. - /// The default value of Infinity disables the sleeping algorithm. - this.sleepTimeThreshold = Infinity; - - /// Amount of encouraged penetration between colliding shapes.. - /// Used to reduce oscillating contacts and keep the collision cache warm. - /// Defaults to 0.1. If you have poor simulation quality, - /// increase this number as much as possible without allowing visible amounts of overlap. - this.collisionSlop = 0.1; - - /// Determines how fast overlapping shapes are pushed apart. - /// Expressed as a fraction of the error remaining after each second. - /// Defaults to pow(1.0 - 0.1, 60.0) meaning that Chipmunk fixes 10% of overlap each frame at 60Hz. - this.collisionBias = Math.pow(1 - 0.1, 60); - - /// Number of frames that contact information should persist. - /// Defaults to 3. There is probably never a reason to change this value. - this.collisionPersistence = 3; - - /// Rebuild the contact graph during each step. Must be enabled to use the cpBodyEachArbiter() function. - /// Disabled by default for a small performance boost. Enabled implicitly when the sleeping feature is enabled. - this.enableContactGraph = false; - - /// The designated static body for this space. - /// You can modify this body, or replace it with your own static body. - /// By default it points to a statically allocated cpBody in the cpSpace struct. - this.staticBody = new Body(Infinity, Infinity); - this.staticBody.nodeIdleTime = Infinity; - - // Cache the collideShapes callback function for the space. - this.collideShapes = this.makeCollideShapes(); -}; - -Space.prototype.getCurrentTimeStep = function() { return this.curr_dt; }; - -Space.prototype.setIterations = function(iter) { this.iterations = iter; }; - -/// returns true from inside a callback and objects cannot be added/removed. -Space.prototype.isLocked = function() -{ - return this.locked; -}; - -var assertSpaceUnlocked = function(space) -{ - assert(!space.locked, "This addition/removal cannot be done safely during a call to cpSpaceStep() \ - or during a query. Put these calls into a post-step callback."); -}; - -// **** Collision handler function management - -/// Set a collision handler to be used whenever the two shapes with the given collision types collide. -/// You can pass null for any function you don't want to implement. -Space.prototype.addCollisionHandler = function(a, b, begin, preSolve, postSolve, separate) -{ - assertSpaceUnlocked(this); - - // Remove any old function so the new one will get added. - this.removeCollisionHandler(a, b); - - var handler = new CollisionHandler(); - handler.a = a; - handler.b = b; - if(begin) handler.begin = begin; - if(preSolve) handler.preSolve = preSolve; - if(postSolve) handler.postSolve = postSolve; - if(separate) handler.separate = separate; - - this.collisionHandlers[hashPair(a, b)] = handler; -}; - -/// Unset a collision handler. -Space.prototype.removeCollisionHandler = function(a, b) -{ - assertSpaceUnlocked(this); - - delete this.collisionHandlers[hashPair(a, b)]; -}; - -/// Set a default collision handler for this space. -/// The default collision handler is invoked for each colliding pair of shapes -/// that isn't explicitly handled by a specific collision handler. -/// You can pass null for any function you don't want to implement. -Space.prototype.setDefaultCollisionHandler = function(begin, preSolve, postSolve, separate) -{ - assertSpaceUnlocked(this); - - var handler = new CollisionHandler(); - if(begin) handler.begin = begin; - if(preSolve) handler.preSolve = preSolve; - if(postSolve) handler.postSolve = postSolve; - if(separate) handler.separate = separate; - - this.defaultHandler = handler; -}; - -Space.prototype.lookupHandler = function(a, b) -{ - return this.collisionHandlers[hashPair(a, b)] || this.defaultHandler; -}; - -// **** Body, Shape, and Joint Management - -/// Add a collision shape to the simulation. -/// If the shape is attached to a static body, it will be added as a static shape. -Space.prototype.addShape = function(shape) -{ - var body = shape.body; - if(body.isStatic()) return this.addStaticShape(shape); - - assert(!shape.space, "This shape is already added to a space and cannot be added to another."); - assertSpaceUnlocked(this); - - body.activate(); - body.addShape(shape); - - shape.update(body.p, body.rot); - this.activeShapes.insert(shape, shape.hashid); - shape.space = this; - - return shape; -}; - -/// Explicity add a shape as a static shape to the simulation. -Space.prototype.addStaticShape = function(shape) -{ - assert(!shape.space, "This shape is already added to a space and cannot be added to another."); - assertSpaceUnlocked(this); - - var body = shape.body; - body.addShape(shape); - - shape.update(body.p, body.rot); - this.staticShapes.insert(shape, shape.hashid); - shape.space = this; - - return shape; -}; - -/// Add a rigid body to the simulation. -Space.prototype.addBody = function(body) -{ - assert(!body.isStatic(), "Static bodies cannot be added to a space as they are not meant to be simulated."); - assert(!body.space, "This body is already added to a space and cannot be added to another."); - assertSpaceUnlocked(this); - - this.bodies.push(body); - body.space = this; - - return body; -}; - -/// Add a constraint to the simulation. -Space.prototype.addConstraint = function(constraint) -{ - assert(!constraint.space, "This shape is already added to a space and cannot be added to another."); - assertSpaceUnlocked(this); - - var a = constraint.a, b = constraint.b; - - a.activate(); - b.activate(); - this.constraints.push(constraint); - - // Push onto the heads of the bodies' constraint lists - constraint.next_a = a.constraintList; a.constraintList = constraint; - constraint.next_b = b.constraintList; b.constraintList = constraint; - constraint.space = this; - - return constraint; -}; - -Space.prototype.filterArbiters = function(body, filter) -{ - for (var hash in this.cachedArbiters) - { - var arb = this.cachedArbiters[hash]; - - // Match on the filter shape, or if it's null the filter body - if( - (body === arb.body_a && (filter === arb.a || filter === null)) || - (body === arb.body_b && (filter === arb.b || filter === null)) - ){ - // Call separate when removing shapes. - if(filter && arb.state !== 'cached') arb.callSeparate(this); - - arb.unthread(); - - deleteObjFromList(this.arbiters, arb); - //this.pooledArbiters.push(arb); - - delete this.cachedArbiters[hash]; - } - } -}; - -/// Remove a collision shape from the simulation. -Space.prototype.removeShape = function(shape) -{ - var body = shape.body; - if(body.isStatic()){ - this.removeStaticShape(shape); - } else { - assert(this.containsShape(shape), - "Cannot remove a shape that was not added to the space. (Removed twice maybe?)"); - assertSpaceUnlocked(this); - - body.activate(); - body.removeShape(shape); - this.filterArbiters(body, shape); - this.activeShapes.remove(shape, shape.hashid); - shape.space = null; - } -}; - -/// Remove a collision shape added using addStaticShape() from the simulation. -Space.prototype.removeStaticShape = function(shape) -{ - assert(this.containsShape(shape), - "Cannot remove a static or sleeping shape that was not added to the space. (Removed twice maybe?)"); - assertSpaceUnlocked(this); - - var body = shape.body; - if(body.isStatic()) body.activateStatic(shape); - body.removeShape(shape); - this.filterArbiters(body, shape); - this.staticShapes.remove(shape, shape.hashid); - shape.space = null; -}; - -/// Remove a rigid body from the simulation. -Space.prototype.removeBody = function(body) -{ - assert(this.containsBody(body), - "Cannot remove a body that was not added to the space. (Removed twice maybe?)"); - assertSpaceUnlocked(this); - - body.activate(); -// this.filterArbiters(body, null); - deleteObjFromList(this.bodies, body); - body.space = null; -}; - -/// Remove a constraint from the simulation. -Space.prototype.removeConstraint = function(constraint) -{ - assert(this.containsConstraint(constraint), - "Cannot remove a constraint that was not added to the space. (Removed twice maybe?)"); - assertSpaceUnlocked(this); - - constraint.a.activate(); - constraint.b.activate(); - deleteObjFromList(this.constraints, constraint); - - constraint.a.removeConstraint(constraint); - constraint.b.removeConstraint(constraint); - constraint.space = null; -}; - -/// Test if a collision shape has been added to the space. -Space.prototype.containsShape = function(shape) -{ - return (shape.space === this); -}; - -/// Test if a rigid body has been added to the space. -Space.prototype.containsBody = function(body) -{ - return (body.space == this); -}; - -/// Test if a constraint has been added to the space. -Space.prototype.containsConstraint = function(constraint) -{ - return (constraint.space == this); -}; - -Space.prototype.uncacheArbiter = function(arb) -{ - delete this.cachedArbiters[hashPair(arb.a.hashid, arb.b.hashid)]; - deleteObjFromList(this.arbiters, arb); -}; - - -// **** Iteration - -/// Call @c func for each body in the space. -Space.prototype.eachBody = function(func) -{ - this.lock(); { - var bodies = this.bodies; - - for(var i=0; i keThreshold ? 0 : body.nodeIdleTime + dt); - } - } - - // Awaken any sleeping bodies found and then push arbiters to the bodies' lists. - var arbiters = this.arbiters; - for(var i=0, count=arbiters.length; i= 0, "Internal Error: Space lock underflow."); - - if(this.locked === 0 && runPostStep){ - var waking = this.rousedBodies; - for(var i=0; i this.collisionPersistence){ - // The tail buffer is available, rotate the ring - var tail = head.next; - tail.stamp = stamp; - tail.contacts.length = 0; - this.contactBuffersHead = tail; - } else { - // Allocate a new buffer and push it into the ring - var buffer = new ContactBuffer(stamp, head); - this.contactBuffersHead = head.next = buffer; - } -}; - -cpContact * -cpContactBufferGetArray(cpSpace *space) -{ - if(space.contactBuffersHead.numContacts + CP_MAX_CONTACTS_PER_ARBITER > CP_CONTACTS_BUFFER_SIZE){ - // contact buffer could overflow on the next collision, push a fresh one. - space.pushFreshContactBuffer(); - } - - cpContactBufferHeader *head = space.contactBuffersHead; - return ((cpContactBuffer *)head)->contacts + head.numContacts; -} - -void -cpSpacePushContacts(cpSpace *space, int count) -{ - cpAssertHard(count <= CP_MAX_CONTACTS_PER_ARBITER, "Internal Error: Contact buffer overflow!"); - space.contactBuffersHead.numContacts += count; -} - -static void -cpSpacePopContacts(cpSpace *space, int count){ - space.contactBuffersHead.numContacts -= count; -} -*/ - -// **** Collision Detection Functions - -/* Use this to re-enable object pools. -static void * -cpSpaceArbiterSetTrans(cpShape **shapes, cpSpace *space) -{ - if(space.pooledArbiters.num == 0){ - // arbiter pool is exhausted, make more - int count = CP_BUFFER_BYTES/sizeof(cpArbiter); - cpAssertHard(count, "Internal Error: Buffer size too small."); - - cpArbiter *buffer = (cpArbiter *)cpcalloc(1, CP_BUFFER_BYTES); - cpArrayPush(space.allocatedBuffers, buffer); - - for(int i=0; i b.collisionCode){ - var temp = a; - a = b; - b = temp; - } - - // Narrow-phase collision detection. - //cpContact *contacts = cpContactBufferGetArray(space); - //int numContacts = cpCollideShapes(a, b, contacts); - var contacts = collideShapes(a, b); - if(contacts.length === 0) return; // Shapes are not colliding. - //cpSpacePushContacts(space, numContacts); - - // Get an arbiter from space.arbiterSet for the two shapes. - // This is where the persistant contact magic comes from. - var arbHash = hashPair(a.hashid, b.hashid); - var arb = space.cachedArbiters[arbHash]; - if (!arb){ - arb = space.cachedArbiters[arbHash] = new Arbiter(a, b); - } - - arb.update(contacts, handler, a, b); - - // Call the begin function first if it's the first step - if(arb.state == 'first coll' && !handler.begin(arb, space)){ - arb.ignore(); // permanently ignore the collision until separation - } - - if( - // Ignore the arbiter if it has been flagged - (arb.state !== 'ignore') && - // Call preSolve - handler.preSolve(arb, space) && - // Process, but don't add collisions for sensors. - !sensor - ){ - space.arbiters.push(arb); - } else { - //cpSpacePopContacts(space, numContacts); - - arb.contacts = null; - - // Normally arbiters are set as used after calling the post-solve callback. - // However, post-solve callbacks are not called for sensors or arbiters rejected from pre-solve. - if(arb.state !== 'ignore') arb.state = 'normal'; - } - - // Time stamp the arbiter so we know it was used recently. - arb.stamp = space.stamp; - }; -}; - -// Hashset filter func to throw away old arbiters. -Space.prototype.arbiterSetFilter = function(arb) -{ - var ticks = this.stamp - arb.stamp; - - var a = arb.body_a, b = arb.body_b; - - // TODO should make an arbiter state for this so it doesn't require filtering arbiters for - // dangling body pointers on body removal. - // Preserve arbiters on sensors and rejected arbiters for sleeping objects. - // This prevents errant separate callbacks from happenening. - if( - (a.isStatic() || a.isSleeping()) && - (b.isStatic() || b.isSleeping()) - ){ - return true; - } - - // Arbiter was used last frame, but not this one - if(ticks >= 1 && arb.state != 'cached'){ - arb.callSeparate(this); - arb.state = 'cached'; - } - - if(ticks >= this.collisionPersistence){ - arb.contacts = null; - - //cpArrayPush(this.pooledArbiters, arb); - return false; - } - - return true; -}; - -// **** All Important cpSpaceStep() Function - -var updateFunc = function(shape) -{ - var body = shape.body; - shape.update(body.p, body.rot); -}; - -/// Step the space forward in time by @c dt. -Space.prototype.step = function(dt) -{ - // don't step if the timestep is 0! - if(dt === 0) return; - - assert(vzero.x === 0 && vzero.y === 0, "vzero is invalid"); - - this.stamp++; - - var prev_dt = this.curr_dt; - this.curr_dt = dt; - - var i; - var j; - var hash; - var bodies = this.bodies; - var constraints = this.constraints; - var arbiters = this.arbiters; - - // Reset and empty the arbiter lists. - for(i=0; imaxForce*(dt)) - -// a and b are bodies. -var relative_velocity = function(a, b, r1, r2){ - //var v1_sum = vadd(a.v, vmult(vperp(r1), a.w)); - var v1_sumx = a.vx + (-r1.y) * a.w; - var v1_sumy = a.vy + ( r1.x) * a.w; - - //var v2_sum = vadd(b.v, vmult(vperp(r2), b.w)); - var v2_sumx = b.vx + (-r2.y) * b.w; - var v2_sumy = b.vy + ( r2.x) * b.w; - -// return vsub(v2_sum, v1_sum); - return new Vect(v2_sumx - v1_sumx, v2_sumy - v1_sumy); -}; - -var normal_relative_velocity = function(a, b, r1, r2, n){ - //return vdot(relative_velocity(a, b, r1, r2), n); - var v1_sumx = a.vx + (-r1.y) * a.w; - var v1_sumy = a.vy + ( r1.x) * a.w; - var v2_sumx = b.vx + (-r2.y) * b.w; - var v2_sumy = b.vy + ( r2.x) * b.w; - - return vdot2(v2_sumx - v1_sumx, v2_sumy - v1_sumy, n.x, n.y); -}; - -/* -var apply_impulse = function(body, j, r){ - body.v = vadd(body.v, vmult(j, body.m_inv)); - body.w += body.i_inv*vcross(r, j); -}; - -var apply_impulses = function(a, b, r1, r2, j) -{ - apply_impulse(a, vneg(j), r1); - apply_impulse(b, j, r2); -}; -*/ - -var apply_impulse = function(body, jx, jy, r){ -// body.v = body.v.add(vmult(j, body.m_inv)); - body.vx += jx * body.m_inv; - body.vy += jy * body.m_inv; -// body.w += body.i_inv*vcross(r, j); - body.w += body.i_inv*(r.x*jy - r.y*jx); -}; - -var apply_impulses = function(a, b, r1, r2, jx, jy) -{ - apply_impulse(a, -jx, -jy, r1); - apply_impulse(b, jx, jy, r2); -}; - -var apply_bias_impulse = function(body, jx, jy, r) -{ - //body.v_bias = vadd(body.v_bias, vmult(j, body.m_inv)); - body.v_biasx += jx * body.m_inv; - body.v_biasy += jy * body.m_inv; - body.w_bias += body.i_inv*vcross2(r.x, r.y, jx, jy); -}; - -/* -var apply_bias_impulses = function(a, b, r1, r2, j) -{ - apply_bias_impulse(a, vneg(j), r1); - apply_bias_impulse(b, j, r2); -};*/ - -var k_scalar_body = function(body, r, n) -{ - var rcn = vcross(r, n); - return body.m_inv + body.i_inv*rcn*rcn; -}; - -var k_scalar = function(a, b, r1, r2, n) -{ - var value = k_scalar_body(a, r1, n) + k_scalar_body(b, r2, n); - assertSoft(value !== 0, "Unsolvable collision or constraint."); - - return value; -}; - -// k1 and k2 are modified by the function to contain the outputs. -var k_tensor = function(a, b, r1, r2, k1, k2) -{ - // calculate mass matrix - // If I wasn't lazy and wrote a proper matrix class, this wouldn't be so gross... - var k11, k12, k21, k22; - var m_sum = a.m_inv + b.m_inv; - - // start with I*m_sum - k11 = m_sum; k12 = 0; - k21 = 0; k22 = m_sum; - - // add the influence from r1 - var a_i_inv = a.i_inv; - var r1xsq = r1.x * r1.x * a_i_inv; - var r1ysq = r1.y * r1.y * a_i_inv; - var r1nxy = -r1.x * r1.y * a_i_inv; - k11 += r1ysq; k12 += r1nxy; - k21 += r1nxy; k22 += r1xsq; - - // add the influnce from r2 - var b_i_inv = b.i_inv; - var r2xsq = r2.x * r2.x * b_i_inv; - var r2ysq = r2.y * r2.y * b_i_inv; - var r2nxy = -r2.x * r2.y * b_i_inv; - k11 += r2ysq; k12 += r2nxy; - k21 += r2nxy; k22 += r2xsq; - - // invert - var determinant = k11*k22 - k12*k21; - assertSoft(determinant !== 0, "Unsolvable constraint."); - - var det_inv = 1/determinant; - - k1.x = k22*det_inv; k1.y = -k12*det_inv; - k2.x = -k21*det_inv; k2.y = k11*det_inv; -}; - -var mult_k = function(vr, k1, k2) -{ - return new Vect(vdot(vr, k1), vdot(vr, k2)); -}; - -var bias_coef = function(errorBias, dt) -{ - return 1 - Math.pow(errorBias, dt); -}; - -/* Copyright (c) 2007 Scott Lembcke - * - * 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. - */ - -// TODO: Comment me! - -// a and b are bodies that the constraint applies to. -var Constraint = cp.Constraint = function(a, b) -{ - /// The first body connected to this constraint. - this.a = a; - /// The second body connected to this constraint. - this.b = b; - - this.space = null; - - this.next_a = null; - this.next_b = null; - - /// The maximum force that this constraint is allowed to use. - this.maxForce = Infinity; - /// The rate at which joint error is corrected. - /// Defaults to pow(1 - 0.1, 60) meaning that it will - /// correct 10% of the error every 1/60th of a second. - this.errorBias = Math.pow(1 - 0.1, 60); - /// The maximum rate at which joint error is corrected. - this.maxBias = Infinity; -}; - -Constraint.prototype.activateBodies = function() -{ - if(this.a) this.a.activate(); - if(this.b) this.b.activate(); -}; - -/// These methods are overridden by the constraint itself. -Constraint.prototype.preStep = function(dt) {}; -Constraint.prototype.applyCachedImpulse = function(dt_coef) {}; -Constraint.prototype.applyImpulse = function() {}; -Constraint.prototype.getImpulse = function() { return 0; }; - -/// Function called before the solver runs. This can be overridden by the user -/// to customize the constraint. -/// Animate your joint anchors, update your motor torque, etc. -Constraint.prototype.preSolve = function(space) {}; - -/// Function called after the solver runs. This can be overridden by the user -/// to customize the constraint. -/// Use the applied impulse to perform effects like breakable joints. -Constraint.prototype.postSolve = function(space) {}; - -Constraint.prototype.next = function(body) -{ - return (this.a === body ? this.next_a : this.next_b); -}; - -/* Copyright (c) 2007 Scott Lembcke - * - * 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 PinJoint = cp.PinJoint = function(a, b, anchr1, anchr2) -{ - Constraint.call(this, a, b); - - this.anchr1 = anchr1; - this.anchr2 = anchr2; - - // STATIC_BODY_CHECK - var p1 = (a ? vadd(a.p, vrotate(anchr1, a.rot)) : anchr1); - var p2 = (b ? vadd(b.p, vrotate(anchr2, b.rot)) : anchr2); - this.dist = vlength(vsub(p2, p1)); - - assertSoft(this.dist > 0, "You created a 0 length pin joint. A pivot joint will be much more stable."); - - this.r1 = this.r2 = null; - this.n = null; - this.nMass = 0; - - this.jnAcc = this.jnMax = 0; - this.bias = 0; -}; - -PinJoint.prototype = Object.create(Constraint.prototype); - -PinJoint.prototype.preStep = function(dt) -{ - var a = this.a; - var b = this.b; - - this.r1 = vrotate(this.anchr1, a.rot); - this.r2 = vrotate(this.anchr2, b.rot); - - var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1)); - var dist = vlength(delta); - this.n = vmult(delta, 1/(dist ? dist : Infinity)); - - // calculate mass normal - this.nMass = 1/k_scalar(a, b, this.r1, this.r2, this.n); - - // calculate bias velocity - var maxBias = this.maxBias; - this.bias = clamp(-bias_coef(this.errorBias, dt)*(dist - this.dist)/dt, -maxBias, maxBias); - - // compute max impulse - this.jnMax = this.maxForce * dt; -}; - -PinJoint.prototype.applyCachedImpulse = function(dt_coef) -{ - var j = vmult(this.n, this.jnAcc*dt_coef); - apply_impulses(this.a, this.b, this.r1, this.r2, j.x, j.y); -}; - -PinJoint.prototype.applyImpulse = function() -{ - var a = this.a; - var b = this.b; - var n = this.n; - - // compute relative velocity - var vrn = normal_relative_velocity(a, b, this.r1, this.r2, n); - - // compute normal impulse - var jn = (this.bias - vrn)*this.nMass; - var jnOld = this.jnAcc; - this.jnAcc = clamp(jnOld + jn, -this.jnMax, this.jnMax); - jn = this.jnAcc - jnOld; - - // apply impulse - apply_impulses(a, b, this.r1, this.r2, n.x*jn, n.y*jn); -}; - -PinJoint.prototype.getImpulse = function() -{ - return Math.abs(this.jnAcc); -}; - -/* Copyright (c) 2007 Scott Lembcke - * - * 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 SlideJoint = cp.SlideJoint = function(a, b, anchr1, anchr2, min, max) -{ - Constraint.call(this, a, b); - - this.anchr1 = anchr1; - this.anchr2 = anchr2; - this.min = min; - this.max = max; - - this.r1 = this.r2 = this.n = null; - this.nMass = 0; - - this.jnAcc = this.jnMax = 0; - this.bias = 0; -}; - -SlideJoint.prototype = Object.create(Constraint.prototype); - -SlideJoint.prototype.preStep = function(dt) -{ - var a = this.a; - var b = this.b; - - this.r1 = vrotate(this.anchr1, a.rot); - this.r2 = vrotate(this.anchr2, b.rot); - - var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1)); - var dist = vlength(delta); - var pdist = 0; - if(dist > this.max) { - pdist = dist - this.max; - this.n = vnormalize_safe(delta); - } else if(dist < this.min) { - pdist = this.min - dist; - this.n = vneg(vnormalize_safe(delta)); - } else { - this.n = vzero; - this.jnAcc = 0; - } - - // calculate mass normal - this.nMass = 1/k_scalar(a, b, this.r1, this.r2, this.n); - - // calculate bias velocity - var maxBias = this.maxBias; - this.bias = clamp(-bias_coef(this.errorBias, dt)*pdist/dt, -maxBias, maxBias); - - // compute max impulse - this.jnMax = this.maxForce * dt; -}; - -SlideJoint.prototype.applyCachedImpulse = function(dt_coef) -{ - var jn = this.jnAcc * dt_coef; - apply_impulses(this.a, this.b, this.r1, this.r2, this.n.x * jn, this.n.y * jn); -}; - -SlideJoint.prototype.applyImpulse = function() -{ - if(this.n.x === 0 && this.n.y === 0) return; // early exit - - var a = this.a; - var b = this.b; - - var n = this.n; - var r1 = this.r1; - var r2 = this.r2; - - // compute relative velocity - var vr = relative_velocity(a, b, r1, r2); - var vrn = vdot(vr, n); - - // compute normal impulse - var jn = (this.bias - vrn)*this.nMass; - var jnOld = this.jnAcc; - this.jnAcc = clamp(jnOld + jn, -this.jnMax, 0); - jn = this.jnAcc - jnOld; - - // apply impulse - apply_impulses(a, b, this.r1, this.r2, n.x * jn, n.y * jn); -}; - -SlideJoint.prototype.getImpulse = function() -{ - return Math.abs(this.jnAcc); -}; - -/* Copyright (c) 2007 Scott Lembcke - * - * 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. - */ - -// Pivot joints can also be created with (a, b, pivot); -var PivotJoint = cp.PivotJoint = function(a, b, anchr1, anchr2) -{ - Constraint.call(this, a, b); - - if(typeof anchr2 === 'undefined') { - var pivot = anchr1; - - anchr1 = (a ? a.world2Local(pivot) : pivot); - anchr2 = (b ? b.world2Local(pivot) : pivot); - } - - this.anchr1 = anchr1; - this.anchr2 = anchr2; - - this.r1 = this.r2 = vzero; - - this.k1 = new Vect(0,0); this.k2 = new Vect(0,0); - - this.jAcc = vzero; - - this.jMaxLen = 0; - this.bias = vzero; -}; - -PivotJoint.prototype = Object.create(Constraint.prototype); - -PivotJoint.prototype.preStep = function(dt) -{ - var a = this.a; - var b = this.b; - - this.r1 = vrotate(this.anchr1, a.rot); - this.r2 = vrotate(this.anchr2, b.rot); - - // Calculate mass tensor. Result is stored into this.k1 & this.k2. - k_tensor(a, b, this.r1, this.r2, this.k1, this.k2); - - // compute max impulse - this.jMaxLen = this.maxForce * dt; - - // calculate bias velocity - var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1)); - this.bias = vclamp(vmult(delta, -bias_coef(this.errorBias, dt)/dt), this.maxBias); -}; - -PivotJoint.prototype.applyCachedImpulse = function(dt_coef) -{ - apply_impulses(this.a, this.b, this.r1, this.r2, this.jAcc.x * dt_coef, this.jAcc.y * dt_coef); -}; - -PivotJoint.prototype.applyImpulse = function() -{ - var a = this.a; - var b = this.b; - - var r1 = this.r1; - var r2 = this.r2; - - // compute relative velocity - var vr = relative_velocity(a, b, r1, r2); - - // compute normal impulse - var j = mult_k(vsub(this.bias, vr), this.k1, this.k2); - var jOld = this.jAcc; - this.jAcc = vclamp(vadd(this.jAcc, j), this.jMaxLen); - - // apply impulse - apply_impulses(a, b, this.r1, this.r2, this.jAcc.x - jOld.x, this.jAcc.y - jOld.y); -}; - -PivotJoint.prototype.getImpulse = function() -{ - return vlength(this.jAcc); -}; - -/* Copyright (c) 2007 Scott Lembcke - * - * 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 GrooveJoint = cp.GrooveJoint = function(a, b, groove_a, groove_b, anchr2) -{ - Constraint.call(this, a, b); - - this.grv_a = groove_a; - this.grv_b = groove_b; - this.grv_n = vperp(vnormalize(vsub(groove_b, groove_a))); - this.anchr2 = anchr2; - - this.grv_tn = null; - this.clamp = 0; - this.r1 = this.r2 = null; - - this.k1 = new Vect(0,0); - this.k2 = new Vect(0,0); - - this.jAcc = vzero; - this.jMaxLen = 0; - this.bias = null; -}; - -GrooveJoint.prototype = Object.create(Constraint.prototype); - -GrooveJoint.prototype.preStep = function(dt) -{ - var a = this.a; - var b = this.b; - - // calculate endpoints in worldspace - var ta = a.local2World(this.grv_a); - var tb = a.local2World(this.grv_b); - - // calculate axis - var n = vrotate(this.grv_n, a.rot); - var d = vdot(ta, n); - - this.grv_tn = n; - this.r2 = vrotate(this.anchr2, b.rot); - - // calculate tangential distance along the axis of r2 - var td = vcross(vadd(b.p, this.r2), n); - // calculate clamping factor and r2 - if(td <= vcross(ta, n)){ - this.clamp = 1; - this.r1 = vsub(ta, a.p); - } else if(td >= vcross(tb, n)){ - this.clamp = -1; - this.r1 = vsub(tb, a.p); - } else { - this.clamp = 0; - this.r1 = vsub(vadd(vmult(vperp(n), -td), vmult(n, d)), a.p); - } - - // Calculate mass tensor - k_tensor(a, b, this.r1, this.r2, this.k1, this.k2); - - // compute max impulse - this.jMaxLen = this.maxForce * dt; - - // calculate bias velocity - var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1)); - this.bias = vclamp(vmult(delta, -bias_coef(this.errorBias, dt)/dt), this.maxBias); -}; - -GrooveJoint.prototype.applyCachedImpulse = function(dt_coef) -{ - apply_impulses(this.a, this.b, this.r1, this.r2, this.jAcc.x * dt_coef, this.jAcc.y * dt_coef); -}; - -GrooveJoint.prototype.grooveConstrain = function(j){ - var n = this.grv_tn; - var jClamp = (this.clamp*vcross(j, n) > 0) ? j : vproject(j, n); - return vclamp(jClamp, this.jMaxLen); -}; - -GrooveJoint.prototype.applyImpulse = function() -{ - var a = this.a; - var b = this.b; - - var r1 = this.r1; - var r2 = this.r2; - - // compute impulse - var vr = relative_velocity(a, b, r1, r2); - - var j = mult_k(vsub(this.bias, vr), this.k1, this.k2); - var jOld = this.jAcc; - this.jAcc = this.grooveConstrain(vadd(jOld, j)); - - // apply impulse - apply_impulses(a, b, this.r1, this.r2, this.jAcc.x - jOld.x, this.jAcc.y - jOld.y); -}; - -GrooveJoint.prototype.getImpulse = function() -{ - return vlength(this.jAcc); -}; - -GrooveJoint.prototype.setGrooveA = function(value) -{ - this.grv_a = value; - this.grv_n = vperp(vnormalize(vsub(this.grv_b, value))); - - this.activateBodies(); -}; - -GrooveJoint.prototype.setGrooveB = function(value) -{ - this.grv_b = value; - this.grv_n = vperp(vnormalize(vsub(value, this.grv_a))); - - this.activateBodies(); -}; - -/* Copyright (c) 2007 Scott Lembcke - * - * 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 defaultSpringForce = function(spring, dist){ - return (spring.restLength - dist)*spring.stiffness; -}; - -var DampedSpring = cp.DampedSpring = function(a, b, anchr1, anchr2, restLength, stiffness, damping) -{ - Constraint.call(this, a, b); - - this.anchr1 = anchr1; - this.anchr2 = anchr2; - - this.restLength = restLength; - this.stiffness = stiffness; - this.damping = damping; - this.springForceFunc = defaultSpringForce; - - this.target_vrn = this.v_coef = 0; - - this.r1 = this.r2 = null; - this.nMass = 0; - this.n = null; -}; - -DampedSpring.prototype = Object.create(Constraint.prototype); - -DampedSpring.prototype.preStep = function(dt) -{ - var a = this.a; - var b = this.b; - - this.r1 = vrotate(this.anchr1, a.rot); - this.r2 = vrotate(this.anchr2, b.rot); - - var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1)); - var dist = vlength(delta); - this.n = vmult(delta, 1/(dist ? dist : Infinity)); - - var k = k_scalar(a, b, this.r1, this.r2, this.n); - assertSoft(k !== 0, "Unsolvable this."); - this.nMass = 1/k; - - this.target_vrn = 0; - this.v_coef = 1 - Math.exp(-this.damping*dt*k); - - // apply this force - var f_spring = this.springForceFunc(this, dist); - apply_impulses(a, b, this.r1, this.r2, this.n.x * f_spring * dt, this.n.y * f_spring * dt); -}; - -DampedSpring.prototype.applyCachedImpulse = function(dt_coef){}; - -DampedSpring.prototype.applyImpulse = function() -{ - var a = this.a; - var b = this.b; - - var n = this.n; - var r1 = this.r1; - var r2 = this.r2; - - // compute relative velocity - var vrn = normal_relative_velocity(a, b, r1, r2, n); - - // compute velocity loss from drag - var v_damp = (this.target_vrn - vrn)*this.v_coef; - this.target_vrn = vrn + v_damp; - - v_damp *= this.nMass; - apply_impulses(a, b, this.r1, this.r2, this.n.x * v_damp, this.n.y * v_damp); -}; - -DampedSpring.prototype.getImpulse = function() -{ - return 0; -}; - -/* Copyright (c) 2007 Scott Lembcke - * - * 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 defaultSpringTorque = function(spring, relativeAngle){ - return (relativeAngle - spring.restAngle)*spring.stiffness; -} - -var DampedRotarySpring = cp.DampedRotarySpring = function(a, b, restAngle, stiffness, damping) -{ - Constraint.call(this, a, b); - - this.restAngle = restAngle; - this.stiffness = stiffness; - this.damping = damping; - this.springTorqueFunc = defaultSpringTorque; - - this.target_wrn = 0; - this.w_coef = 0; - this.iSum = 0; -}; - -DampedRotarySpring.prototype = Object.create(Constraint.prototype); - -DampedRotarySpring.prototype.preStep = function(dt) -{ - var a = this.a; - var b = this.b; - - var moment = a.i_inv + b.i_inv; - assertSoft(moment !== 0, "Unsolvable spring."); - this.iSum = 1/moment; - - this.w_coef = 1 - Math.exp(-this.damping*dt*moment); - this.target_wrn = 0; - - // apply this torque - var j_spring = this.springTorqueFunc(this, a.a - b.a)*dt; - a.w -= j_spring*a.i_inv; - b.w += j_spring*b.i_inv; -}; - -// DampedRotarySpring.prototype.applyCachedImpulse = function(dt_coef){}; - -DampedRotarySpring.prototype.applyImpulse = function() -{ - var a = this.a; - var b = this.b; - - // compute relative velocity - var wrn = a.w - b.w;//normal_relative_velocity(a, b, r1, r2, n) - this.target_vrn; - - // compute velocity loss from drag - // not 100% certain spring is derived correctly, though it makes sense - var w_damp = (this.target_wrn - wrn)*this.w_coef; - this.target_wrn = wrn + w_damp; - - //apply_impulses(a, b, this.r1, this.r2, vmult(this.n, v_damp*this.nMass)); - var j_damp = w_damp*this.iSum; - a.w += j_damp*a.i_inv; - b.w -= j_damp*b.i_inv; -}; - -// DampedRotarySpring.prototype.getImpulse = function(){ return 0; }; - -/* Copyright (c) 2007 Scott Lembcke - * - * 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 RotaryLimitJoint = cp.RotaryLimitJoint = function(a, b, min, max) -{ - Constraint.call(this, a, b); - - this.min = min; - this.max = max; - - this.jAcc = 0; - - this.iSum = this.bias = this.jMax = 0; -}; - -RotaryLimitJoint.prototype = Object.create(Constraint.prototype); - -RotaryLimitJoint.prototype.preStep = function(dt) -{ - var a = this.a; - var b = this.b; - - var dist = b.a - a.a; - var pdist = 0; - if(dist > this.max) { - pdist = this.max - dist; - } else if(dist < this.min) { - pdist = this.min - dist; - } - - // calculate moment of inertia coefficient. - this.iSum = 1/(1/a.i + 1/b.i); - - // calculate bias velocity - var maxBias = this.maxBias; - this.bias = clamp(-bias_coef(this.errorBias, dt)*pdist/dt, -maxBias, maxBias); - - // compute max impulse - this.jMax = this.maxForce * dt; - - // If the bias is 0, the joint is not at a limit. Reset the impulse. - if(!this.bias) this.jAcc = 0; -}; - -RotaryLimitJoint.prototype.applyCachedImpulse = function(dt_coef) -{ - var a = this.a; - var b = this.b; - - var j = this.jAcc*dt_coef; - a.w -= j*a.i_inv; - b.w += j*b.i_inv; -}; - -RotaryLimitJoint.prototype.applyImpulse = function() -{ - if(!this.bias) return; // early exit - - var a = this.a; - var b = this.b; - - // compute relative rotational velocity - var wr = b.w - a.w; - - // compute normal impulse - var j = -(this.bias + wr)*this.iSum; - var jOld = this.jAcc; - if(this.bias < 0){ - this.jAcc = clamp(jOld + j, 0, this.jMax); - } else { - this.jAcc = clamp(jOld + j, -this.jMax, 0); - } - j = this.jAcc - jOld; - - // apply impulse - a.w -= j*a.i_inv; - b.w += j*b.i_inv; -}; - -RotaryLimitJoint.prototype.getImpulse = function() -{ - return Math.abs(joint.jAcc); -}; - -/* Copyright (c) 2007 Scott Lembcke - * - * 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 RatchetJoint = cp.RatchetJoint = function(a, b, phase, ratchet) -{ - Constraint.call(this, a, b); - - this.angle = 0; - this.phase = phase; - this.ratchet = ratchet; - - // STATIC_BODY_CHECK - this.angle = (b ? b.a : 0) - (a ? a.a : 0); - - this.iSum = this.bias = this.jAcc = this.jMax = 0; -}; - -RatchetJoint.prototype = Object.create(Constraint.prototype); - -RatchetJoint.prototype.preStep = function(dt) -{ - var a = this.a; - var b = this.b; - - var angle = this.angle; - var phase = this.phase; - var ratchet = this.ratchet; - - var delta = b.a - a.a; - var diff = angle - delta; - var pdist = 0; - - if(diff*ratchet > 0){ - pdist = diff; - } else { - this.angle = Math.floor((delta - phase)/ratchet)*ratchet + phase; - } - - // calculate moment of inertia coefficient. - this.iSum = 1/(a.i_inv + b.i_inv); - - // calculate bias velocity - var maxBias = this.maxBias; - this.bias = clamp(-bias_coef(this.errorBias, dt)*pdist/dt, -maxBias, maxBias); - - // compute max impulse - this.jMax = this.maxForce * dt; - - // If the bias is 0, the joint is not at a limit. Reset the impulse. - if(!this.bias) this.jAcc = 0; -}; - -RatchetJoint.prototype.applyCachedImpulse = function(dt_coef) -{ - var a = this.a; - var b = this.b; - - var j = this.jAcc*dt_coef; - a.w -= j*a.i_inv; - b.w += j*b.i_inv; -}; - -RatchetJoint.prototype.applyImpulse = function() -{ - if(!this.bias) return; // early exit - - var a = this.a; - var b = this.b; - - // compute relative rotational velocity - var wr = b.w - a.w; - var ratchet = this.ratchet; - - // compute normal impulse - var j = -(this.bias + wr)*this.iSum; - var jOld = this.jAcc; - this.jAcc = clamp((jOld + j)*ratchet, 0, this.jMax*Math.abs(ratchet))/ratchet; - j = this.jAcc - jOld; - - // apply impulse - a.w -= j*a.i_inv; - b.w += j*b.i_inv; -}; - -RatchetJoint.prototype.getImpulse = function(joint) -{ - return Math.abs(joint.jAcc); -}; - -/* Copyright (c) 2007 Scott Lembcke - * - * 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 GearJoint = cp.GearJoint = function(a, b, phase, ratio) -{ - Constraint.call(this, a, b); - - this.phase = phase; - this.ratio = ratio; - this.ratio_inv = 1/ratio; - - this.jAcc = 0; - - this.iSum = this.bias = this.jMax = 0; -}; - -GearJoint.prototype = Object.create(Constraint.prototype); - -GearJoint.prototype.preStep = function(dt) -{ - var a = this.a; - var b = this.b; - - // calculate moment of inertia coefficient. - this.iSum = 1/(a.i_inv*this.ratio_inv + this.ratio*b.i_inv); - - // calculate bias velocity - var maxBias = this.maxBias; - this.bias = clamp(-bias_coef(this.errorBias, dt)*(b.a*this.ratio - a.a - this.phase)/dt, -maxBias, maxBias); - - // compute max impulse - this.jMax = this.maxForce * dt; -}; - -GearJoint.prototype.applyCachedImpulse = function(dt_coef) -{ - var a = this.a; - var b = this.b; - - var j = this.jAcc*dt_coef; - a.w -= j*a.i_inv*this.ratio_inv; - b.w += j*b.i_inv; -}; - -GearJoint.prototype.applyImpulse = function() -{ - var a = this.a; - var b = this.b; - - // compute relative rotational velocity - var wr = b.w*this.ratio - a.w; - - // compute normal impulse - var j = (this.bias - wr)*this.iSum; - var jOld = this.jAcc; - this.jAcc = clamp(jOld + j, -this.jMax, this.jMax); - j = this.jAcc - jOld; - - // apply impulse - a.w -= j*a.i_inv*this.ratio_inv; - b.w += j*b.i_inv; -}; - -GearJoint.prototype.getImpulse = function() -{ - return Math.abs(this.jAcc); -}; - -GearJoint.prototype.setRatio = function(value) -{ - this.ratio = value; - this.ratio_inv = 1/value; - this.activateBodies(); -}; - -/* Copyright (c) 2007 Scott Lembcke - * - * 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 SimpleMotor = cp.SimpleMotor = function(a, b, rate) -{ - Constraint.call(this, a, b); - - this.rate = rate; - - this.jAcc = 0; - - this.iSum = this.jMax = 0; -}; - -SimpleMotor.prototype = Object.create(Constraint.prototype); - -SimpleMotor.prototype.preStep = function(dt) -{ - // calculate moment of inertia coefficient. - this.iSum = 1/(this.a.i_inv + this.b.i_inv); - - // compute max impulse - this.jMax = this.maxForce * dt; -}; - -SimpleMotor.prototype.applyCachedImpulse = function(dt_coef) -{ - var a = this.a; - var b = this.b; - - var j = this.jAcc*dt_coef; - a.w -= j*a.i_inv; - b.w += j*b.i_inv; -}; - -SimpleMotor.prototype.applyImpulse = function() -{ - var a = this.a; - var b = this.b; - - // compute relative rotational velocity - var wr = b.w - a.w + this.rate; - - // compute normal impulse - var j = -wr*this.iSum; - var jOld = this.jAcc; - this.jAcc = clamp(jOld + j, -this.jMax, this.jMax); - j = this.jAcc - jOld; - - // apply impulse - a.w -= j*a.i_inv; - b.w += j*b.i_inv; -}; - -SimpleMotor.prototype.getImpulse = function() -{ - return Math.abs(this.jAcc); -}; - -})(); diff --git a/external/gaf/GAFBoot.js b/external/gaf/GAFBoot.js index 0baccc7ecd..e69de29bb2 100644 --- a/external/gaf/GAFBoot.js +++ b/external/gaf/GAFBoot.js @@ -1,24 +0,0 @@ -var gaf = gaf || {}; -gaf._tmp = gaf._tmp || {}; -gaf._initialized = false; - -gaf.CCGAFLoader = function() -{ - this.load = function(realUrl, url, item, cb) - { - if(!gaf._initialized) - { - gaf._setup(); - } - var loader = new gaf.Loader(); - loader.LoadFile(realUrl, function(data){cb(null, data)}); - }; -}; - -gaf._setup = function() -{ - gaf._setupShaders(); - gaf._initialized = true; -}; - -cc.loader.register('.gaf', new gaf.CCGAFLoader()); diff --git a/external/gaf/GAFMacros.js b/external/gaf/GAFMacros.js index ef34cc8f5d..e69de29bb2 100644 --- a/external/gaf/GAFMacros.js +++ b/external/gaf/GAFMacros.js @@ -1,33 +0,0 @@ -var gaf = gaf || {}; - -gaf.COMPRESSION_NONE = 0x00474146; -gaf.COMPRESSION_ZIP = 0x00474143; - -gaf.IDNONE = 0xffffffff; -gaf.FIRST_FRAME_INDEX = 0; - -gaf.EFFECT_DROP_SHADOW = 0; -gaf.EFFECT_BLUR = 1; -gaf.EFFECT_GLOW = 2; -gaf.EFFECT_COLOR_MATRIX = 6; - -gaf.ACTION_STOP = 0; -gaf.ACTION_PLAY = 1; -gaf.ACTION_GO_TO_AND_STOP = 2; -gaf.ACTION_GO_TO_AND_PLAY = 3; -gaf.ACTION_DISPATCH_EVENT = 4; - -gaf.PI_FRAME = 0; -gaf.PI_EVENT_TYPE = 0; - -gaf.TYPE_TEXTURE = 0; -gaf.TYPE_TEXT_FIELD = 1; -gaf.TYPE_TIME_LINE = 2; - -gaf.UNIFORM_BLUR_TEXEL_OFFSET = "u_step"; -gaf.UNIFORM_GLOW_TEXEL_OFFSET = "u_step"; -gaf.UNIFORM_GLOW_COLOR = "u_glowColor"; -gaf.UNIFORM_ALPHA_TINT_MULT = "colorTransformMult"; -gaf.UNIFORM_ALPHA_TINT_OFFSET = "colorTransformOffsets"; -gaf.UNIFORM_ALPHA_COLOR_MATRIX_BODY = "colorMatrix"; -gaf.UNIFORM_ALPHA_COLOR_MATRIX_APPENDIX = "colorMatrix2"; diff --git a/external/gaf/Library/GAFAsset.js b/external/gaf/Library/GAFAsset.js index 23804e61ff..e69de29bb2 100644 --- a/external/gaf/Library/GAFAsset.js +++ b/external/gaf/Library/GAFAsset.js @@ -1,429 +0,0 @@ -var gaf = gaf || {}; - -gaf.Asset = cc.Class.extend -({ - _className: "GAFAsset", - - // Private members - _header: null, - _timeLines: null, - _textFields: null, - _protos: null, - _objects: null, - _masks: null, - - _rootTimeLine: null, - _textureLoadDelegate: null, - _sceneFps: 60, - _sceneWidth: 0, - _sceneHeight: 0, - _sceneColor: 0, - _gafData: null, - _desiredAtlasScale: 1, - _usedAtlasScale: 0, - - _atlases: null, - _onLoadTasks: null, - _atlasScales: null, - _textureLoaded: false, // For async loading with cc.event manager - _atlasesToLoad: null, // Atlases that are not yet loaded - _gafName: null, - - /** - * @method initWithGAFFile - * @param {String} filePath - path to .gaf file - * @param {String function(String)} textureLoadDelegate - is used to change atlas path, e.g. to load `atlas.tga` instead of `atlas.png` - * @return {bool} - */ - initWithGAFFile: function (filePath, textureLoadDelegate) { - var self = this; - this._textureLoadDelegate = textureLoadDelegate; - this._gafName = filePath; - var gafData = cc.loader.getRes(filePath); - if(!gafData) - { - cc.loader.load(filePath, function(err, data){ - if(!err) - { - self._init(data[0]); - } - }); - } - else { - return this._init(gafData); - } - return false; - }, - - /** - * @method initWithGAFBundle - * @param {String} zipFilePath - path to the archive with .gaf and its textures - * @param {String} entryFile - name of the .gaf file in archive - * @param {function({path:String})} delegate - is used to change atlas path, e.g. to load `atlas.tga` instead of `atlas.png` - * @return {bool} - */ - initWithGAFBundle: function (zipFilePath, entryFile, delegate) - { - cc.assert(false, "initWithGAFBundle is not yet implemented"); - return false; - }, - - /** - * @method setRootTimelineWithName - * @param {String} name - */ - setRootTimelineWithName: function (name) - { - for(var i = 0, end = this._timeLines.length; i < end; ++i) - { - var object = this._timeLines[i]; - if (object && object.getLinkageName() === name) - { - this._setRootTimeline(object); - return; - } - } - }, - -/* addEventListener: function(name, listener) - {},*/ - - isAssetVersionPlayable: function () - { - return true; - }, - - /** - * Desired atlas scale. - * Default is 1.0f - * @returns {number} - */ - desiredAtlasScale : function(){ - return this._desiredAtlasScale; - }, - - /** - * Sets desired atlas scale. Will choose nearest atlas scale from available. - * Default is 1.0f - * @param scale - */ - setDesiredAtlasScale : function(desiredAtlasScale){ - this._desiredAtlasScale = desiredAtlasScale; - for(var currentScale in this._atlasScales)if(this._atlasScales.hasOwnProperty(currentScale)) - { - if( (this._usedAtlasScale === 0) || - (Math.abs(this._usedAtlasScale - desiredAtlasScale) > Math.abs(currentScale - desiredAtlasScale) )) - { - this._usedAtlasScale = currentScale; - } - - } - }, - - /** - * @method createObject - * @return {gaf.Object} - */ - createObject: function () - { - return this._instantiateGaf(this._gafData); - }, - - /** - * @method createObjectAndRun - * @param {boolean} arg0 - run looped - * @return {gaf.Object} - */ - createObjectAndRun: function (looped) - { - cc.assert(arguments.length === 1, "GAFAsset::createObjectAndRun should have one param"); - var object = this._instantiateGaf(this._gafData); - object.setLooped(looped, true); - object.start(); - return object; - }, - - /** - * @method setTextureLoadDelegate - * @param {function} delegate - */ - setTextureLoadDelegate: function (delegate) - { - debugger; - }, - - - /** - * @method getSceneFps - * @return {uint} - */ - getSceneFps: function () - { - return this._sceneFps; - }, - - /** - * @method getSceneWidth - * @return {uint} - */ - getSceneWidth: function () - { - debugger; - }, - - /** - * @method getSceneHeight - * @return {uint} - */ - getSceneHeight: function () - { - debugger; - }, - - /** - * @method getSceneColor - * @return {cc.color4b} - */ - getSceneColor: function () - { - debugger; - }, - - /** - * @method setSceneFps - * @param {uint} fps - */ - setSceneFps: function (fps) - { - this._sceneFps = fps; - }, - - /** - * @method setSceneWidth - * @param {uint} width - */ - setSceneWidth: function (width) - { - debugger; - }, - - /** - * @method setSceneHeight - * @param {uint} height - */ - setSceneHeight: function (height) - { - debugger; - }, - - /** - * @method setSceneColor - * @param {color4b_object} arg0 - */ - setSceneColor: function (color4B) - { - debugger; - }, - - /** - * @method getHeader - * @return {GAFHeader} - */ - getHeader: function () - { - return this._header; - }, - - getGAFFileName: function() - { - return this._gafName; - }, - - // Private - - ctor : function() - { - this._header = {}; - this._timeLines = []; - this._textFields = []; - this._objects = []; - this._masks = []; - this._protos = []; - this._atlases = {}; - this._onLoadTasks = []; - this._atlasScales = {}; - this._atlasesToLoad = {}; - - if(arguments.length > 0) - this.initWithGAFFile.apply(this, arguments); - }, - - _getProtos: function() - { - return this._protos; - }, - - _setRootTimeline : function(timeLine) - { - this._rootTimeLine = timeLine; - this._header.pivot = timeLine.getPivot(); - this._header.frameSize = timeLine.getRect(); - }, - - _setHeader : function (gafHeader) - { - for(var prop in gafHeader) - { - if(gafHeader.hasOwnProperty(prop)) - { - this._header[prop] = gafHeader[prop]; - } - } - }, - - _getMajorVerison : function() - { - return this._header.versionMajor; - }, - - _init : function(gafData) - { - var self = this; - this._gafData = gafData; - this._setHeader(gafData.header); - this._timeLinesToLink = []; - if(this._getMajorVerison() < 4) - { - this._pushTimeLine(new gaf._TimeLineProto(this, this._header.framesCount, this._header.frameSize, this._header.pivot)); - } - gaf._AssetPreload.Tags(this, gafData.tags, this._rootTimeLine); - - //Link and create - this._objects.forEach(function(item) - { - switch(item.type) - { - case gaf.TYPE_TEXTURE: - // Create gaf sprite proto if it is not yet created - if(!self._protos[item.objectId]) - { - self._protos[item.objectId] = new gaf._SpriteProto(self, self._atlasScales, item.elementAtlasIdRef); - } - break; - case gaf.TYPE_TIME_LINE: - // All time line protos are already created, just copy reference - self._protos[item.objectId] = self._timeLines[item.elementAtlasIdRef]; - break; - case gaf.TYPE_TEXT_FIELD: - // All text field protos are already created, just copy reference - self._protos[item.objectId] = self._textFields[item.elementAtlasIdRef]; - break; - default: - cc.log("Unknown object type: " + item.type); - break; - } - }); - this._masks.forEach(function(item) - { - if(self._protos[item.objectId]) - { - return; // this is continue - } - var proto = null; - switch(item.type) - { - case gaf.TYPE_TEXTURE: - // Create gaf sprite proto if it is not yet created - proto = new gaf._SpriteProto(self, self._atlasScales, item.elementAtlasIdRef); - break; - case gaf.TYPE_TIME_LINE: - // All time line protos are already created, just copy reference - proto = self._timeLines[item.elementAtlasIdRef]; - break; - case gaf.TYPE_TEXT_FIELD: - // All text field protos are already created, just copy reference - proto = self._textFields[item.elementAtlasIdRef]; - break; - } - self._protos[item.objectId] = new gaf._MaskProto(self, proto, item.elementAtlasIdRef); - }); - this.setDesiredAtlasScale(this._desiredAtlasScale); - - if(Object.keys(this._atlasesToLoad).length === 0) - { - this._textureLoaded = true; - this.dispatchEvent("load"); - } - }, - - _pushTimeLine : function(timeLine) - { - this._timeLines[timeLine.getId()] = timeLine; - - if(timeLine.getId() === 0) - { - this._setRootTimeline(timeLine); - } - }, - - _instantiateGaf : function() - { - var root = null; - root = this._rootTimeLine._gafConstruct(); - return root; - }, - - _onAtlasLoaded : function(id, atlas) - { - this._atlases[id] = atlas; - delete this._atlasesToLoad[id]; - if(Object.keys(this._atlasesToLoad).length === 0) - { - this._onLoadTasks.forEach(function(fn){fn()}); - this._onLoadTasks.length = 0; - this._textureLoaded = true; - this.dispatchEvent("load"); - } - }, - - isLoaded : function() - { - return this._textureLoaded; - }, - - _getSearchPaths: function(imageUrl) - { - var extendedPath = this.getGAFFileName().split('/'); - extendedPath[extendedPath.length-1] = imageUrl; - var alternativeUrl = extendedPath.join('/'); - - return [imageUrl, alternativeUrl]; - } -}); - -/** - * @method initWithGAFFile - * @param {String} gafFilePath - path to .gaf file - * @param {function({path:String})} delegate - is used to change atlas path, e.g. to load `atlas.tga` instead of `atlas.png` - * @return {gaf.Asset} - */ -gaf.Asset.create = function (gafFilePath, delegate) -{ - return new gaf.Asset(gafFilePath, delegate); -}; - -/** - * @method createWithBundle - * @param {String} zipFilePath - path to the archive with .gaf and its textures - * @param {String} entryFile - name of the .gaf file in archive - * @param {function({path:String})} delegate - is used to change atlas path, e.g. to load `atlas.tga` instead of `atlas.png` - * @return {gaf.Asset} - */ -gaf.Asset.createWithBundle = function (zipFilePath, entryFile, delegate) -{ - var asset = new gaf.Asset(); - asset.initWithGAFBundle(zipFilePath, entryFile, delegate); - return asset; -}; - -cc.EventHelper.prototype.apply(gaf.Asset.prototype); diff --git a/external/gaf/Library/GAFAssetPreload.js b/external/gaf/Library/GAFAssetPreload.js index 8514e09f2d..e69de29bb2 100644 --- a/external/gaf/Library/GAFAssetPreload.js +++ b/external/gaf/Library/GAFAssetPreload.js @@ -1,270 +0,0 @@ - -gaf.CGAffineTransformCocosFormatFromFlashFormat = function(transform) -{ - var t = {}; - t.a = transform.a; - t.b = -transform.b; - t.c = -transform.c; - t.d = transform.d; - t.tx = transform.tx; - t.ty = -transform.ty; - return t; -}; - -gaf._AssetPreload = function() -{ - this["0"] = this.End; - this["1"] = this.Atlases; - this["2"] = this.AnimationMasks; - this["3"] = this.AnimationObjects; - this["4"] = this.AnimationFrames; - this["5"] = this.NamedParts; - this["6"] = this.Sequences; - this["7"] = this.TextFields; - this["8"] = this.Atlases; // 2 - this["9"] = this.Stage; - this["10"] = this.AnimationObjects; //2 - this["11"] = this.AnimationMasks; // 2 - this["12"] = this.AnimationFrames; // 2 - this["13"] = this.TimeLine; -}; - -gaf._AssetPreload.prototype.End = function(asset, content, timeLine){ - if(timeLine) - { - timeLine.getFps = function() - { - return asset.getSceneFps(); - }; - } -}; - -gaf._AssetPreload.prototype.Tag = function(asset, tag, timeLine) -{ - (this[tag.tagId]).call(this, asset, tag.content, timeLine); -}; - -gaf._AssetPreload.prototype.Tags = function(asset, tags, timeLine) -{ - var self = this; - tags.forEach(function(tag) - { - self.Tag(asset, tag, timeLine); - }); -}; - -gaf._AssetPreload.prototype.AtlasCreateFrames = function(elements, asset, spriteFrames) -{ - elements.forEach(function (item) { - var texture = asset._atlases[item.atlasId]; - var rect = cc.rect(item.origin.x, item.origin.y, item.size.x, item.size.y); - var frame = new cc.SpriteFrame(texture, rect); - frame._gafAnchor = - { - x: (0 - (0 - (item.pivot.x / item.size.x))), - y: (0 + (1 - (item.pivot.y / item.size.y))) - }; - spriteFrames[item.elementAtlasId] = frame; - // 9 grid - }); -}; - - - -gaf._AssetPreload.prototype.Atlases = function(asset, content, timeLine) -{ - var spriteFrames = asset._atlasScales[content.scale] = asset._atlasScales[content.scale] || []; - var csf = cc.Director._getInstance().getContentScaleFactor(); - - content.atlases.forEach(function(item) - { - var atlasId = item.id; - var finalizeLoading = function() - { - gaf._AssetPreload.AtlasCreateFrames(content.elements, asset, spriteFrames); - }; - - var atlasPath = ""; - item.sources.forEach(function(atlasSource) - { - if(atlasSource.csf === csf) - { - atlasPath = atlasSource.source; - } - }); - cc.assert(atlasPath, "GAF Error. Texture for current CSF not found. Reconvert animation with correct parameters."); - - if(asset._textureLoadDelegate) - { - atlasPath = asset._textureLoadDelegate(atlasPath); - } - - var loaded = false; - var paths = asset._getSearchPaths(atlasPath); - for(var i = 0, len = paths.length; i < len; ++i){ - var path = paths[i]; - var atlas = cc.textureCache.getTextureForKey(path); - if(atlas && atlas.isLoaded()) - { - atlas.handleLoadedTexture(true); - loaded = true; - asset._atlases[atlasId] = atlas; - finalizeLoading(); - break; - } - } - // Need to load atlases async - if(!loaded) - { - var success = function (atlas) { - atlas.handleLoadedTexture(true); - asset._onAtlasLoaded(atlasId, atlas); - }; - - var fail = function () { - cc.log("GAF Error. Couldn't find `" + atlasPath + "` required by `" + asset.getGAFFileName() + "`"); - }; - - if(!asset._atlasesToLoad.hasOwnProperty(atlasId)) - { - gaf._AtlasLoader.loadArray(paths, success, fail); - asset._atlasesToLoad[atlasId] = {}; - } - asset._onLoadTasks.push(finalizeLoading); - } - }); -}; - -gaf._AssetPreload.prototype.AnimationObjects = function(asset, content, timeLine) -{ - content.forEach(function(item) - { - item.type = (item.type === undefined) ? gaf.TYPE_TEXTURE : item.type; - timeLine._objects.push(item.objectId); - asset._objects[item.objectId] = item; - }); -}; - -gaf._AssetPreload.prototype.convertTint = function(mat, alpha) -{ - if(!mat) - return null; - return { - mult: - { - r: mat.redMultiplier * 255, - g: mat.greenMultiplier * 255, - b: mat.blueMultiplier * 255, - a: alpha * 255 - }, - offset: - { - r: mat.redOffset * 255, - g: mat.greenOffset * 255, - b: mat.blueOffset * 255, - a: mat.alphaOffset * 255 - } - }; -}; - -gaf._AssetPreload.prototype.convertState = function(state) -{ - return { - hasColorTransform: state.hasColorTransform, - hasMask: state.hasMask, - hasEffect: state.hasEffect, - objectIdRef: state.objectIdRef, - depth: state.depth, - alpha: state.alpha * 255, - matrix: gaf.CGAffineTransformCocosFormatFromFlashFormat(state.matrix), - colorTransform: this.convertTint(state.colorTransform, state.alpha), - effect: state.effect, - maskObjectIdRef: state.maskObjectIdRef - }; -}; - -gaf._AssetPreload.prototype.AnimationFrames = function(asset, content, timeLine) -{ - var self = this; - cc.assert(timeLine, "Error. Time Line should not be null."); - var statesForId = {}; - var frames = []; - var lastFrame = {}; - for(var i = 0, len = content.length; i < len; ++i) - { - var frame = content[i]; - if(frame.state) - { - frame.state.forEach(function (state) - { - if (state.alpha !== 0) - { - statesForId[state.objectIdRef] = self.convertState(state); - } - else - { - statesForId[state.objectIdRef] = null; - } - }); - } - var stateArray = []; - for(var obj in statesForId){ if(statesForId.hasOwnProperty(obj) && statesForId[obj]) - { - stateArray.push(statesForId[obj]); - }} - lastFrame = frame; - frames[frame.frame - 1] = {states: stateArray, actions: frame.actions || null}; - } - timeLine.getFrames = function(){return frames}; -}; - -gaf._AssetPreload.prototype.NamedParts = function(asset, content, timeLine) -{ - var parts = {}; - content.forEach(function(item) - { - parts[item.name] = item.objectId; - }); - timeLine.getNamedParts = function(){return parts}; -}; - -gaf._AssetPreload.prototype.Sequences = function(asset, content, timeLine) -{ - var sequences = {}; - content.forEach(function(item){ - sequences[item.id] = {start: item.start - 1, end: item.end}; - }); - timeLine.getSequences = function(){return sequences}; -}; - -gaf._AssetPreload.prototype.TextFields = function(asset, content, timeLine) -{ - debugger; -}; - -gaf._AssetPreload.prototype.Stage = function(asset, content, timeLine) -{ - asset._sceneFps = content.fps; - asset._sceneColor = content.color; - asset._sceneWidth = content.width; - asset._sceneHeight = content.height; -}; - -gaf._AssetPreload.prototype.AnimationMasks = function(asset, content, timeLine) -{ - content.forEach(function(item) - { - item.type = (item.type === undefined) ? gaf.TYPE_TEXTURE : item.type; - timeLine._objects.push(item.objectId); - asset._masks[item.objectId] = item; - }); -}; - -gaf._AssetPreload.prototype.TimeLine = function(asset, content, timeLine) -{ - var result = new gaf._TimeLineProto(asset, content.animationFrameCount, content.boundingBox, content.pivotPoint, content.id, content.linkageName); - asset._pushTimeLine(result); - this.Tags(asset, content.tags, result); -}; - -gaf._AssetPreload = new gaf._AssetPreload(); diff --git a/external/gaf/Library/GAFAtlasLoader.js b/external/gaf/Library/GAFAtlasLoader.js index 152bba0788..e69de29bb2 100644 --- a/external/gaf/Library/GAFAtlasLoader.js +++ b/external/gaf/Library/GAFAtlasLoader.js @@ -1,50 +0,0 @@ -/** - * Created by admiral on 19.02.2015. - */ - -gaf._AtlasLoader = {}; -gaf._AtlasLoader.execute = function(condition, success, fail) -{ - condition() ? success() : fail(); -}; - -gaf._AtlasLoader.checkAtlas = function(atlas) // curried function -{ - return function(){return atlas && typeof atlas !== "string" && atlas.isLoaded()}; -}; - -gaf._AtlasLoader.load = function(path, success, fail) -{ - cc.textureCache.addImage(path, function(atlas){ - gaf._AtlasLoader.execute( - gaf._AtlasLoader.checkAtlas(atlas), - function(){success(atlas)}, - fail - ); - }); -}; - -gaf._AtlasLoader.loadFront = function(arr, success, fail) -{ - // Call recursively this function for each element starting from the first - // stops on first success, or fails after last element - return function() - { - if (arr.length > 0){ - gaf._AtlasLoader.load( - arr[0], - success, - gaf._AtlasLoader.loadFront( - arr.slice(1), - success, - fail - ));} - else - fail(); - } -}; - -gaf._AtlasLoader.loadArray = function(array, success, fail) -{ - gaf._AtlasLoader.loadFront(array, success, fail)(); -}; diff --git a/external/gaf/Library/GAFDataReader.js b/external/gaf/Library/GAFDataReader.js index 3affbe1335..e69de29bb2 100644 --- a/external/gaf/Library/GAFDataReader.js +++ b/external/gaf/Library/GAFDataReader.js @@ -1,229 +0,0 @@ -gaf.DataReader = function(data) { - this.dataRaw = data; - this.buf = new DataView(data); - this.offset = [0]; -}; - -gaf.DataReader.prototype.constructor = gaf.DataReader; - -gaf.DataReader.prototype.newOffset = function(size){ - this.offset[this.offset.length - 1] += size; - if(this.getOffset() > this.maxOffset()){ - throw new Error("GAF format error"); - } - return this.offset[this.offset.length - 1] - size; -}; - -gaf.DataReader.prototype.maxOffset = function(){ - if(this.offset.length == 1){ - return this.buf.byteLength; - } - else{ - return this.offset[this.offset.length - 2]; - } -}; - -gaf.DataReader.prototype.getOffset = function(size){ - return this.offset[this.offset.length - 1]; -}; - -gaf.DataReader.prototype.Ubyte = function() { - return this.buf.getUint8(this.newOffset(1)); -}; - -gaf.DataReader.prototype.Boolean = function() { - var result = this.buf.getUint8(this.newOffset(1)); - if(result > 1){ - throw new Error("GAF format error"); - } - return result; -}; - -gaf.DataReader.prototype.Uint = function() { - return this.buf.getUint32(this.newOffset(4), true); -}; - -gaf.DataReader.prototype.Int = function() { - return this.buf.getInt32(this.newOffset(4), true); -}; - -gaf.DataReader.prototype.color = function() { - return { - b: this.Ubyte(), - g: this.Ubyte(), - r: this.Ubyte(), - a: this.Ubyte() - }; -}; - -gaf.DataReader.prototype.Ushort = function() { - return this.buf.getUint16(this.newOffset(2), true); -}; - -gaf.DataReader.prototype.Float = function() { - return this.buf.getFloat32(this.newOffset(4), true); -}; - -gaf.DataReader.prototype.String = function() { - var strLen = this.Ushort(); - var from = this.newOffset(strLen); - var to = this.getOffset(); - - try - { - var str = this.dataRaw.slice(from, to); - } - catch(e) - { - // Internet Explorer 10 T.T - if(e.message == "Object doesn't support property or method 'slice'") - { - str = []; - for(var i = from; i < to; ++i) - str.push(this.buf.getUint8(i)); - } - else - { - throw(e); - } - } - return decodeURIComponent(escape(String.fromCharCode.apply(null, new Uint8Array(str)))); - -}; - -gaf.DataReader.prototype.startNestedBuffer = function(length) { - this.offset.push(this.offset[this.offset.length-1]); - this.offset[this.offset.length-2] += length; -}; - -gaf.DataReader.prototype.endNestedBuffer = function() { - if (this.offset.length == 1) throw new Error('No nested buffer available'); - this.offset.pop(); -}; - -gaf.DataReader.prototype.Point = function(){ - return { - x: this.Float(), - y: this.Float() - }; -}; - -gaf.DataReader.prototype.Rect = function(){ - return { - x: this.Float(), - y: this.Float(), - width: this.Float(), - height: this.Float() - }; -}; - -gaf.DataReader.prototype.Matrix = function(){ - return { - a: this.Float(), - b: this.Float(), - c: this.Float(), - d: this.Float(), - tx: this.Float(), - ty: this.Float() - }; -}; - -gaf.DataReader.prototype.seek = function(pos){ - this.offset[this.offset.length-1] = pos; -}; - -gaf.DataReader.prototype.tell = function(){ - return this.offset[this.offset.length-1]; -}; - -/* Creates a fields parsing function -* @ returns a function that will read from DataReader `field` of type `type` -* @`key` - key for read data to be stored -* @`data` - data to store. Can be DataReader function name or a function that will return a value -* Note. Parameters pair `key` and `data` can be repeated any number of times*/ - -gaf.DataReader.prototype.fields = function(){ - var self = this; - var arguments_ = arguments; - return function(){ - arguments.callee.result = {}; - var i = 0; - if(arguments_.length % 2){ - throw new Error('Number of arguments is not even'); - } - while(i < arguments_.length){ - var field = arguments_[i++]; - var func = arguments_[i++]; - if(typeof func === 'function'){ - arguments.callee.result[field] = func(); - } - else if (func in self && typeof self[func] === 'function'){ - arguments.callee.result[field] = self[func].call(self); - } - else{ - throw new Error('Object DataReader has no function `' + func + '`'); - } - } - return arguments.callee.result; - } -}; - -/* -* Creates a parsing function -* @ returns function that will execute expression if caller's `result` field has `key` equal to `value` parameter -* @ `key` - key in caller's `result` element -* @ `value` - expected value of the `key` or a comparator function -* @ `func` - function to execute if condition is true -* */ - -gaf.DataReader.prototype.condition = function(key, value, func){ - var arguments_ = arguments; - return function() { - if(arguments_.length != 3){ - throw new Error('Condition function'); - } - var parent = arguments.callee.caller; - if(!('result' in parent)){ - throw new Error('Condition function caller has no key `result`'); - } - var container = parent.result; - var field = arguments_[0]; - var value = arguments_[1]; - var exec = arguments_[2]; - - var evaluate = null; - if(typeof value === 'function'){ - evaluate = function(){return value(container[field]);}; - } - else{ - evaluate = function(){return value == container[field];}; - } - if(evaluate()){ - return exec(); - } - else{ - return null; - } - } -}; - -/* -* Creates an array parsing function -* @ returns function that will execute `func` number of times read from DataReader -* @ `type` - type of count number -* @ `func` - function to be executed -* */ - -gaf.DataReader.prototype.array = function(){ - var self = this; - var arguments_ = arguments; - return function() { - arguments.callee.result = []; - var length = self[arguments_[0]].call(self); - for (var i = 0; i < length; ++i) { - var r = arguments_[1].call(); - arguments.callee.result.push(r); - } - return arguments.callee.result; - } -}; diff --git a/external/gaf/Library/GAFLoader.js b/external/gaf/Library/GAFLoader.js index 3e40c33947..e69de29bb2 100644 --- a/external/gaf/Library/GAFLoader.js +++ b/external/gaf/Library/GAFLoader.js @@ -1,75 +0,0 @@ -var gaf = gaf || {}; - -//@Private class -gaf.Loader = function(){ - - var readHeaderBegin = function(stream, header){ - header.compression = stream.Uint(); - header.versionMajor = stream.Ubyte(); - header.versionMinor = stream.Ubyte(); - header.fileLength = stream.Uint(); - }; - - var readHeaderEndV3 = function(stream, header) { - header.framesCount = stream.Ushort(); - header.frameSize = stream.Rect(); - header.pivot = stream.Point(); - }; - - var readHeaderEndV4 = function(stream, header){ - var scaleCount = stream.Uint(); - header.scaleValues = []; - for(var i = 0; i < scaleCount; ++i){ - header.scaleValues.push(stream.Float()); - } - var csfCount = stream.Uint(); - header.csfValues = []; - for(var i = 0; i < csfCount; ++i){ - header.csfValues.push(stream.Float()); - } - }; - - this.LoadFile = function(filePath, onLoaded){ - var oReq = new XMLHttpRequest(); - oReq.open("GET", filePath, true); - var self = this; - oReq.responseType = "arraybuffer"; - oReq.onload = function(oEvent) { - var gaf_data = new gaf.DataReader(oReq.response); - var gafFile = self.LoadStream(gaf_data); - if(onLoaded) - onLoaded(gafFile); - }; - oReq.send(); - }; - - this.LoadStream = function(stream){ - var header = {}; - readHeaderBegin(stream, header); - if(header.compression == gaf.COMPRESSION_NONE) { // GAF - } - else if(header.compression == gaf.COMPRESSION_ZIP){ // GAC - var compressed = stream.dataRaw.slice(stream.tell()); - - var inflate = new window.Zlib.Inflate(new Uint8Array(compressed)); - var decompressed = inflate.decompress(); - stream = new gaf.DataReader(decompressed.buffer); - } - else{ - throw new Error("GAF syntax error."); - } - - if(header.versionMajor < 4){ - readHeaderEndV3(stream, header); - } - else{ - readHeaderEndV4(stream, header); - } - - var tags = gaf.ReadTags(stream); - return { - header: header, - tags: tags - }; - }; -}; diff --git a/external/gaf/Library/GAFMask.js b/external/gaf/Library/GAFMask.js index 34ca20681c..e69de29bb2 100644 --- a/external/gaf/Library/GAFMask.js +++ b/external/gaf/Library/GAFMask.js @@ -1,36 +0,0 @@ - -gaf.Mask = gaf.Object.extend -({ - _className: "GAFMask", - _clippingNode: null, - - ctor : function(gafSpriteProto) - { - this._super(); - cc.assert(gafSpriteProto, "Error! Missing mandatory parameter."); - this._gafproto = gafSpriteProto; - }, - - _init : function() - { - var maskNodeProto = this._gafproto.getMaskNodeProto(); - cc.assert(maskNodeProto, "Error. Mask node for id ref " + this._gafproto.getIdRef() + " not found."); - this._maskNode = maskNodeProto._gafConstruct(); - this._clippingNode = cc.ClippingNode.create(this._maskNode); - this._clippingNode.setAlphaThreshold(0.5); - this.addChild(this._clippingNode); - }, - - setExternalTransform : function(affineTransform) - { - if(!cc.affineTransformEqualToTransform(this._maskNode._additionalTransform, affineTransform)) - { - this._maskNode.setAdditionalTransform(affineTransform); - } - }, - - _getNode : function() - { - return this._clippingNode; - } -}); \ No newline at end of file diff --git a/external/gaf/Library/GAFMaskProto.js b/external/gaf/Library/GAFMaskProto.js index 6074fd1279..e69de29bb2 100644 --- a/external/gaf/Library/GAFMaskProto.js +++ b/external/gaf/Library/GAFMaskProto.js @@ -1,16 +0,0 @@ - -gaf._MaskProto = function(asset, mask, idRef) -{ - this.getIdRef = function(){return idRef}; - this.getMaskNodeProto = function() {return mask}; - - /* - * Will construct GAFMask - */ - this._gafConstruct = function() - { - var ret = new gaf.Mask(this); - ret._init(); - return ret; - }; -}; diff --git a/external/gaf/Library/GAFObject.js b/external/gaf/Library/GAFObject.js index 7d5375abe5..e69de29bb2 100644 --- a/external/gaf/Library/GAFObject.js +++ b/external/gaf/Library/GAFObject.js @@ -1,426 +0,0 @@ -var gaf = gaf || {}; - -gaf._stateHasCtx = function(state) -{ - // Check for tint color offset - if( state.hasColorTransform && - (state.colorTransform.offset.r > 0 || - state.colorTransform.offset.g > 0 || - state.colorTransform.offset.b > 0 || - state.colorTransform.offset.a > 0) - ) - { - return true; - } - - // Check for color transform filter - if(state.hasEffect) - { - for(var i = 0, total = state.effect.length; i < total; ++i) - { - if(state.effect[i].type === gaf.EFFECT_COLOR_MATRIX) - return true; - } - } - return false; -}; - -gaf.Object = cc.Node.extend -({ - _asset : null, - _className : "GAFObject", - _id : gaf.IDNONE, - _gafproto : null, - _parentTimeLine : null, - _lastVisibleInFrame : 0, - _filterStack : null, - _cascadeColorMult : null, - _cascadeColorOffset : null, - _needsCtx : false, - _usedAtlasScale: 1, - - // Public methods - ctor: function(scale) - { - if(arguments.length == 1) - { - this._usedAtlasScale = scale; - } - this._super(); - this._cascadeColorMult = cc.color(255, 255, 255, 255); - this._cascadeColorOffset = cc.color(0, 0, 0, 0); - this._filterStack = []; - }, - - /** - * @method setAnimationStartedNextLoopDelegate - * @param {function(Object)} delegate - */ - setAnimationStartedNextLoopDelegate : function (delegate) {}, - - /** - * @method setAnimationFinishedPlayDelegate - * @param {function(Object)} delegate - */ - setAnimationFinishedPlayDelegate : function (delegate) {}, - - /** - * @method setLooped - * @param {bool} looped - */ - setLooped : function (looped) {}, - - /** - * @method getBoundingBoxForCurrentFrame - * @return {cc.Rect} - */ - getBoundingBoxForCurrentFrame : function () {return null;}, - - /** - * @method setFps - * @param {uint} fps - */ - setFps : function (fps) {}, - - /** - * @method getObjectByName - * @param {String} name - name of the object to find - * @return {gaf.Object} - */ - getObjectByName : function (name) {return null;}, - - /** - * @method clearSequence - */ - clearSequence : function () {}, - - /** - * @method getIsAnimationRunning - * @return {bool} - */ - getIsAnimationRunning : function () {return false;}, - - /** - * @method getSequences - * @return [string] - list of sequences if has any - */ - getSequences : function(){return [];}, - - - /** - * @method gotoAndStop - * @param {uint|String} value - label ot frame number - * @return {bool} - */ - gotoAndStop : function (value) {}, - - /** - * @method getStartFrame - * @param {String} frameLabel - * @return {uint} - */ - getStartFrame : function (frameLabel) {return gaf.IDNONE;}, - - /** - * @method setFramePlayedDelegate - * @param {function(Object, frame)} delegate - */ - setFramePlayedDelegate : function (delegate) {}, - - /** - * @method getCurrentFrameIndex - * @return {uint} - */ - getCurrentFrameIndex : function () { - return gaf.IDNONE; - }, - - /** - * @method getTotalFrameCount - * @return {uint} - */ - getTotalFrameCount : function () {return 0;}, - - /** - * @method start - */ - start : function () {}, - - /** - * @method stop - */ - stop : function () {}, - - /** - * @method isVisibleInCurrentFrame - * @return {bool} - */ - isVisibleInCurrentFrame : function () - { - /*if (this._parentTimeLine && - ((this._parentTimeLine.getCurrentFrameIndex() + 1) != this._lastVisibleInFrame)) - { - return false; - } - else - { - return true; - }*/ - return !(this._parentTimeLine && ((this._parentTimeLine.getCurrentFrameIndex() + 1) != this._lastVisibleInFrame)); - }, - - /** - * @method isDone - * @return {bool} - */ - isDone : function () {return true;}, - - /** - * @method playSequence - * @param {String} name - name of the sequence to play - * @param {bool} looped - play looped - * @param {bool} resume - whether to resume animation if stopped. True by default - * @return {bool} - */ - playSequence : function (name, looped, resume) {return false;}, - - /** - * @method isReversed - * @return {bool} - */ - isReversed : function () {return false;}, - - /** - * @method setSequenceDelegate - * @param {function(Object, sequenceName)} delegate - */ - setSequenceDelegate : function (delegate) {}, - - /** - * @method setFrame - * @param {uint} index - * @return {bool} - */ - setFrame : function (index) {return false;}, - - /** - * @method setControlDelegate - * @param {function} func - */ - setControlDelegate : function (func) {}, - - /** - * @method getEndFrame - * @param {String} frameLabel - * @return {uint} - */ - getEndFrame : function (frameLabel) {return gaf.IDNONE;}, - - /** - * @method pauseAnimation - */ - pauseAnimation : function () {}, - - /** - * @method gotoAndPlay - * @param {uint|String} value - label ot frame number - * @return {bool} - */ - gotoAndPlay : function (value) {}, - - /** - * @method isLooped - * @return {bool} - */ - isLooped : function () {return false;}, - - /** - * @method resumeAnimation - */ - resumeAnimation : function () {}, - - /** - * @method setReversed - * @param {bool} reversed - */ - setReversed : function (reversed) {}, - - /** - * @method hasSequences - * @return {bool} - */ - hasSequences : function () {return false;}, - - /** - * @method getFps - * @return {uint} - */ - getFps : function () {return 60;}, - - /** - * @method setLocator - * @param {bool} locator - * Locator object will not draw itself, but its children will be drawn - */ - setLocator : function (locator){}, - - setExternalTransform : function(affineTransform) - { - if(!cc.affineTransformEqualToTransform(this._additionalTransform, affineTransform)) - { - this.setAdditionalTransform(affineTransform); - } - }, - - getExternalTransform : function() - { - return this._additionalTransform; - }, - - setAnimationRunning: function () {}, - - //////////////// - // Private - //////////////// - _enableTick: function(val){}, - - _resetState : function() - {}, - - _updateVisibility : function(state, parent) - { - var alphaOffset = state.hasColorTransform ? state.colorTransform.offset.a : 0; - this.setOpacity(state.alpha + alphaOffset); - //return this.isVisible(); - }, - - // @Override - isVisible : function() - { - return this.getOpacity() > 0; - }, - - // @Override - visit: function(parentCmd) - { - if(this.isVisibleInCurrentFrame()) - { - this._super(parentCmd); - } - }, - - _getFilters : function(){return null}, - - _processAnimation : function(){}, - - - _applyState : function(state, parent) - { - this._applyStateSuper(state, parent); - }, - - _applyStateSuper : function(state, parent) - { - this._needsCtx = parent._needsCtx; - this._filterStack.length = 0; // clear - this._parentTimeLine = parent; // only gaf time line can call applyState. Assign it as parent - if(this._usedAtlasScale != 1) - { - var newMat = cc.clone(state.matrix); - newMat.tx *= this._usedAtlasScale; - newMat.ty *= this._usedAtlasScale; - this.setExternalTransform(newMat); // apply transformations of the state - } - else - { - this.setExternalTransform(state.matrix); // apply transformations of the state - } - // Cascade filters - // TODO: apply more than one filter - if (state.hasEffect) { - this._filterStack = this._filterStack.concat(state.effect); - this._needsCtx = true; - } - if (parent._filterStack && parent._filterStack.length > 0) { - this._filterStack = this._filterStack.concat(parent._filterStack); - } - - if(this._filterStack.length > 0 && this._filterStack[0].type === gaf.EFFECT_COLOR_MATRIX) - { - this._needsCtx = true; - } - - // Cascade color transformations - - // If state has a tint, then we should process it - if (state.hasColorTransform) - { - this._cascadeColorMult.r = state.colorTransform.mult.r * parent._cascadeColorMult.r / 255; - this._cascadeColorMult.g = state.colorTransform.mult.g * parent._cascadeColorMult.g / 255; - this._cascadeColorMult.b = state.colorTransform.mult.b * parent._cascadeColorMult.b / 255; - this._cascadeColorMult.a = state.colorTransform.mult.a * parent._cascadeColorMult.a / 255; - - this._cascadeColorOffset.r = state.colorTransform.offset.r + parent._cascadeColorOffset.r; - this._cascadeColorOffset.g = state.colorTransform.offset.g + parent._cascadeColorOffset.g; - this._cascadeColorOffset.b = state.colorTransform.offset.b + parent._cascadeColorOffset.b; - this._cascadeColorOffset.a = state.colorTransform.offset.a + parent._cascadeColorOffset.a; - } - else - { - this._cascadeColorMult.r = parent._cascadeColorMult.r; - this._cascadeColorMult.g = parent._cascadeColorMult.g; - this._cascadeColorMult.b = parent._cascadeColorMult.b; - this._cascadeColorMult.a = state.alpha * (parent._cascadeColorMult.a / 255); - - this._cascadeColorOffset.r = parent._cascadeColorOffset.r; - this._cascadeColorOffset.g = parent._cascadeColorOffset.g; - this._cascadeColorOffset.b = parent._cascadeColorOffset.b; - this._cascadeColorOffset.a = parent._cascadeColorOffset.a; - } - - if (this._cascadeColorOffset.r > 0 || - this._cascadeColorOffset.g > 0 || - this._cascadeColorOffset.b > 0 || - this._cascadeColorOffset.a > 0) - { - this._needsCtx = true; - } - }, - - _initRendererCmd: function() - { - this._renderCmd = cc.renderer.getRenderCmd(this); - this._renderCmd._visit = this._renderCmd.visit; - var self = this; - this._renderCmd.visit = function(parentCmd) { - if(self.isVisibleInCurrentFrame()){ - this._visit(parentCmd); - } - } - }, - - _getNode : function() - { - return this; - }, - - setAnchorPoint : function(point, y) - { - if (y === undefined) - { - this._super(point.x, point.y - 1); - } - else - { - this._super(point, y - 1); - } - } - -}); - -gaf.Object._createNullObject = function() -{ - var ret = new gaf.Object(); - ret.isVisible = function(){return true}; - return ret; -}; diff --git a/external/gaf/Library/GAFShaderManager.js b/external/gaf/Library/GAFShaderManager.js index 49b7ffba0f..e69de29bb2 100644 --- a/external/gaf/Library/GAFShaderManager.js +++ b/external/gaf/Library/GAFShaderManager.js @@ -1,63 +0,0 @@ - -gaf._glShaderInit = function() { - gaf._Uniforms = { - ColorTransformMult: -1, - ColorTransformOffset: -1, - ColorMatrixBody: -1, - ColorMatrixAppendix: -1, - BlurTexelOffset: -1, - GlowTexelOffset: -1, - GlowColor: -1 - }; - - gaf._shaderCreate = function (fs, vs) { - var program = new cc.GLProgram(); - var result = program.initWithVertexShaderByteArray(vs, fs); - cc.assert(result, "Shader init error"); - program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION); - program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR); - program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS); - result = program.link(); - cc.assert(result, "Shader linking error"); - program.updateUniforms(); - return program; - }; - - gaf._shaderCreateAlpha = function () { - var program = gaf._shaderCreate(gaf.SHADER_COLOR_MATRIX_FRAG, cc.SHADER_POSITION_TEXTURE_COLOR_VERT); - gaf._Uniforms.ColorTransformMult = program.getUniformLocationForName(gaf.UNIFORM_ALPHA_TINT_MULT); - gaf._Uniforms.ColorTransformOffset = program.getUniformLocationForName(gaf.UNIFORM_ALPHA_TINT_OFFSET); - gaf._Uniforms.ColorMatrixBody = program.getUniformLocationForName(gaf.UNIFORM_ALPHA_COLOR_MATRIX_BODY); - gaf._Uniforms.ColorMatrixAppendix = program.getUniformLocationForName(gaf.UNIFORM_ALPHA_COLOR_MATRIX_APPENDIX); - return program; - }; - - gaf._shaderCreateBlur = function () { - var program = gaf._shaderCreate(gaf.SHADER_GAUSSIAN_BLUR_FRAG, cc.SHADER_POSITION_TEXTURE_COLOR_VERT); - gaf._Uniforms.BlurTexelOffset = program._glContext.getUniformLocation(program._programObj, gaf.UNIFORM_BLUR_TEXEL_OFFSET); - - return program; - }; - - gaf._shaderCreateGlow = function () { - var program = gaf._shaderCreate(gaf.SHADER_GLOW_FRAG, cc.SHADER_POSITION_TEXTURE_COLOR_VERT); - gaf._Uniforms.GlowTexelOffset = program._glContext.getUniformLocation(program._programObj, gaf.UNIFORM_GLOW_TEXEL_OFFSET); - gaf._Uniforms.GlowColor = program._glContext.getUniformLocation(program._programObj, gaf.UNIFORM_GLOW_COLOR); - return program; - }; - - gaf._Shaders = { - Alpha: gaf._shaderCreateAlpha(), - Blur: gaf._shaderCreateBlur(), - Glow: gaf._shaderCreateGlow() - }; -}; - -gaf._setupShaders = function() { - if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) { - gaf._glShaderInit(); - } - else { - delete gaf._glShaderInit; - } -}; diff --git a/external/gaf/Library/GAFShaders.js b/external/gaf/Library/GAFShaders.js index 7d91537285..e69de29bb2 100644 --- a/external/gaf/Library/GAFShaders.js +++ b/external/gaf/Library/GAFShaders.js @@ -1,58 +0,0 @@ -gaf.SHADER_GAUSSIAN_BLUR_FRAG = - "varying mediump vec2 v_texCoord;\n" - + "uniform mediump vec2 u_step;\n" - + "void main()\n" - + "{ \n" - + " mediump vec4 sum = vec4(0.0); \n" - + " sum += texture2D(CC_Texture0, v_texCoord - u_step * 4.0) * 0.05; \n" - + " sum += texture2D(CC_Texture0, v_texCoord - u_step * 3.0) * 0.09; \n" - + " sum += texture2D(CC_Texture0, v_texCoord - u_step * 2.0) * 0.12; \n" - + " sum += texture2D(CC_Texture0, v_texCoord - u_step * 1.0) * 0.15; \n" - + " sum += texture2D(CC_Texture0, v_texCoord + u_step * 0.0) * 0.18; \n" - + " sum += texture2D(CC_Texture0, v_texCoord + u_step * 1.0) * 0.15; \n" - + " sum += texture2D(CC_Texture0, v_texCoord + u_step * 2.0) * 0.12; \n" - + " sum += texture2D(CC_Texture0, v_texCoord + u_step * 3.0) * 0.09; \n" - + " sum += texture2D(CC_Texture0, v_texCoord + u_step * 4.0) * 0.05; \n" - + " gl_FragColor = sum; \n" - + "} \n"; - -gaf.SHADER_GLOW_FRAG = - "varying mediump vec2 v_texCoord;\n" - + "uniform mediump vec2 u_step;\n" - + "uniform mediump vec4 u_glowColor;\n" - + "void main()\n" - + "{ \n" - + " mediump vec4 sum = vec4(0.0); \n" - + " sum += texture2D(CC_Texture0, v_texCoord - u_step * 4.0) * 0.05; \n" - + " sum += texture2D(CC_Texture0, v_texCoord - u_step * 3.0) * 0.09; \n" - + " sum += texture2D(CC_Texture0, v_texCoord - u_step * 2.0) * 0.12; \n" - + " sum += texture2D(CC_Texture0, v_texCoord - u_step * 1.0) * 0.15; \n" - + " sum += texture2D(CC_Texture0, v_texCoord + u_step * 0.0) * 0.18; \n" - + " sum += texture2D(CC_Texture0, v_texCoord + u_step * 1.0) * 0.15; \n" - + " sum += texture2D(CC_Texture0, v_texCoord + u_step * 2.0) * 0.12; \n" - + " sum += texture2D(CC_Texture0, v_texCoord + u_step * 3.0) * 0.09; \n" - + " sum += texture2D(CC_Texture0, v_texCoord + u_step * 4.0) * 0.05; \n" - + " gl_FragColor = sum * u_glowColor; \n" - + "} \n"; - -gaf.SHADER_COLOR_MATRIX_FRAG = - "varying mediump vec2 v_texCoord;\n" - + "varying mediump vec4 v_fragmentColor;\n" - + "uniform mediump vec4 colorTransformMult;\n" - + "uniform mediump vec4 colorTransformOffsets;\n" - + "uniform mediump mat4 colorMatrix;\n" - + "uniform mediump vec4 colorMatrix2;\n" - + "void main()\n" - + "{ \n" - + " vec4 texColor = texture2D(CC_Texture0, v_texCoord); \n" - + " const float kMinimalAlphaAllowed = 1.0e-8; \n" - + " if (texColor.a > kMinimalAlphaAllowed) \n" - + " { \n" - + " texColor = vec4(texColor.rgb / texColor.a, texColor.a); \n" - + " vec4 ctxColor = texColor * colorTransformMult + colorTransformOffsets; \n" - + " vec4 adjustColor = colorMatrix * ctxColor + colorMatrix2; \n" - + " adjustColor *= v_fragmentColor; \n" - + " texColor = vec4(adjustColor.rgb * adjustColor.a, adjustColor.a); \n" - + " } \n" - + " gl_FragColor = texColor; \n" - + "}\n"; diff --git a/external/gaf/Library/GAFSprite.js b/external/gaf/Library/GAFSprite.js index 2387bf92df..e69de29bb2 100644 --- a/external/gaf/Library/GAFSprite.js +++ b/external/gaf/Library/GAFSprite.js @@ -1,100 +0,0 @@ - -gaf.Sprite = gaf.Object.extend -({ - _className: "GAFSprite", - - _hasCtx: false, - _hasFilter: false, - - ctor : function(gafSpriteProto, usedScale) - { - this._super(usedScale); - cc.assert(gafSpriteProto, "Error! Missing mandatory parameter."); - this._gafproto = gafSpriteProto; - }, - - // Private - - _init : function() - { - var frame = this._gafproto.getFrame(); - cc.assert(frame instanceof cc.SpriteFrame, "Error. Wrong object type."); - - // Create sprite with custom render command from frame - this._sprite = new cc.Sprite(); - this._sprite._renderCmd = this._gafCreateRenderCmd(this._sprite); - this._sprite.initWithSpriteFrame(frame); - - this._sprite.setAnchorPoint(this._gafproto.getAnchor()); - this.addChild(this._sprite); - //this._sprite.setCascadeColorEnabled(true); - //this._sprite.setCascadeOpacityEnabled(true); - this._sprite.setOpacityModifyRGB(true); - - if(cc._renderType === cc.game.RENDER_TYPE_WEBGL) - this._sprite.setBlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); - }, - - _applyState : function(state, parent) - { - this._applyStateSuper(state, parent); - if(this._needsCtx) - { - // Enable ctx state if wasn't enabled - if(!this._hasCtx) - { - this._enableCtx(); - this._hasCtx = true; - } - // Set ctx shader - this._applyCtxState(state); - } - else - { - // Disable ctx state if was enabled - if(this._hasCtx) - { - this._disableCtx(); - this._hasCtx = false; - } - // Apply color - if(!cc.colorEqual(this._sprite._realColor, this._cascadeColorMult)) - { - this._sprite.setColor(this._cascadeColorMult); - } - // Apply opacity - if(this._sprite.getOpacity() != this._cascadeColorMult.a) - { - this._sprite.setOpacity(this._cascadeColorMult.a); - } - - } - }, - - _enableCtx: function() - { - this._sprite._renderCmd._enableCtx(); - }, - - _disableCtx: function() - { - this._sprite._renderCmd._disableCtx(); - }, - - _applyCtxState: function(state){ - this._sprite._renderCmd._applyCtxState(this); - }, - - getBoundingBoxForCurrentFrame: function () - { - var result = this._sprite.getBoundingBox(); - return cc._rectApplyAffineTransformIn(result, this.getNodeToParentTransform()); - }, - - _gafCreateRenderCmd: function(item){ - if(cc._renderType === cc.game.RENDER_TYPE_CANVAS) - return new gaf.Sprite.CanvasRenderCmd(item); - else - return new gaf.Sprite.WebGLRenderCmd(item); - } -}); diff --git a/external/gaf/Library/GAFSpriteCanvasRenderCmd.js b/external/gaf/Library/GAFSpriteCanvasRenderCmd.js index bb807cc220..e69de29bb2 100644 --- a/external/gaf/Library/GAFSpriteCanvasRenderCmd.js +++ b/external/gaf/Library/GAFSpriteCanvasRenderCmd.js @@ -1,233 +0,0 @@ - -(function() { - gaf.Sprite.CanvasRenderCmd = function (renderable) { - cc.Sprite.CanvasRenderCmd.call(this, renderable); - this._hasTintMult = false; - this._hasTintOffset = false; - this._hasCtx = false; - this._tintMult = cc.color(255,255,255,255); - this._tintOffset = cc.color(0,0,0,0); - this._textureDirty = false; - }; - var proto = gaf.Sprite.CanvasRenderCmd.prototype = Object.create(cc.Sprite.CanvasRenderCmd.prototype); - proto.constructor = gaf.Sprite.CanvasRenderCmd; - - proto._disableCtx = function(){ - this._hasTintOffset = false; - this._hasCtx = false; - this._textureDirty = true; - this.setDirtyFlag(cc.Node._dirtyFlags.colorDirty); - this._tintMult = cc.color(255,255,255,255); - this._tintOffset = cc.color(0,0,0,0); - }; - - proto._enableCtx = function(){ - - }; - - proto._applyCtxState = function(gafObject){ - - var tintMult = gafObject._cascadeColorMult; - var tintOffset = gafObject._cascadeColorOffset; - var opacity = tintMult.a; - - // Apply opacity - if(this._node.getOpacity() != opacity) - { - this._node.setOpacity(opacity); - } - - // Check Tint multiplicator - var multDirty = !cc.colorEqual(this._tintMult, tintMult); - if(multDirty) - { - this._node.setColor(tintMult); - this._tintMult = tintMult; - this._hasTintMult = - (tintMult.r !== 255 || - tintMult.g !== 255 || - tintMult.b !== 255 ); - } - - // Check Tint offset - var offfsetDirty = - (this._tintOffset.r != tintOffset.r) || - (this._tintOffset.g != tintOffset.g) || - (this._tintOffset.b != tintOffset.b) || - (this._tintOffset.a != tintOffset.a); - - if(offfsetDirty) - { - this._tintOffset = tintOffset; - this._hasTintOffset = - (tintOffset.r !== 0 || - tintOffset.g !== 0 || - tintOffset.b !== 0 || - tintOffset.a !== 0 ); - } - - // Update dirty flag - this._textureDirty = multDirty || offfsetDirty; - if(this._textureDirty) - { - this.setDirtyFlag(cc.Node._dirtyFlags.colorDirty); - } - - - this._hasCtx = gafObject._filterStack.length > 0 && gafObject._filterStack[0].type === gaf.EFFECT_COLOR_MATRIX; - - }; - - proto.rendering = function(ctx, scaleX, scaleY) - { - var node = this._node; - var locTextureCoord = this._textureCoord, - alpha = (this._displayedOpacity / 255); - - if ((node._texture && ((locTextureCoord.width === 0 || locTextureCoord.height === 0) //set texture but the texture isn't loaded. - || !node._texture._textureLoaded)) || alpha === 0) - return; - - var wrapper = ctx || cc._renderContext, - context = wrapper.getContext(); - var locX = node._offsetPosition.x, - locHeight = node._rect.height, - locWidth = node._rect.width, - locY = -node._offsetPosition.y - locHeight, - image; - - wrapper.setTransform(this._worldTransform, scaleX, scaleY); - wrapper.setCompositeOperation(this._blendFuncStr); - wrapper.setGlobalAlpha(alpha); - - if(node._flippedX || node._flippedY) - wrapper.save(); - if (node._flippedX) { - locX = -locX - locWidth; - context.scale(-1, 1); - } - if (node._flippedY) { - locY = node._offsetPosition.y; - context.scale(1, -1); - } - - image = node._texture._htmlElementObj; - - if (this._colorized) { - context.drawImage(image, - 0, 0, locTextureCoord.width,locTextureCoord.height, - locX * scaleX,locY * scaleY, locWidth * scaleX, locHeight * scaleY); - } else { - context.drawImage(image, - locTextureCoord.renderX, locTextureCoord.renderY, locTextureCoord.width, locTextureCoord.height, - locX * scaleX, locY * scaleY, locWidth * scaleX, locHeight * scaleY); - } - - if(node._flippedX || node._flippedY) - wrapper.restore(); - cc.g_NumberOfDraws++; - }; - - if(cc.sys._supportCanvasNewBlendModes){ - proto._updateColor = function () { - var displayedColor = this._displayedColor, node = this._node; - this._hasTintMult |= (displayedColor.r !== 255 || displayedColor.g !== 255 || displayedColor.b !== 255); - - // If no color changes - if(this._textureDirty) - { - this._textureDirty = false; - if (this._colorized) { - this._colorized = false; - node.texture = this._originalTexture; - } - } - else - { - return; - } - - var locElement, locTexture = node._texture, locRect = this._textureCoord; - if(this._hasTintMult) - { - if (locTexture && locRect.validRect && this._originalTexture) { - locElement = locTexture.getHtmlElementObj(); - if (!locElement) - return; - - this._colorized = true; - if (this._hasTintOffset || this._hasCtx) displayedColor = this._tintMult; - - locElement = cc.Sprite.CanvasRenderCmd._generateTintImageWithMultiply(this._originalTexture._htmlElementObj, displayedColor, locRect); - locTexture = new cc.Texture2D(); - locTexture.initWithElement(locElement); - locTexture.handleLoadedTexture(); - node.texture = locTexture; - } - } - - locTexture = node._texture; - if(this._hasTintOffset) - { - var cacheTextureForColor = cc.textureCache.getTextureColors(this._originalTexture.getHtmlElementObj()); - if (locTexture && locRect.validRect && this._originalTexture) { - locElement = locTexture.getHtmlElementObj(); - if (!locElement) - return; - if(this._colorized) - var texRect = cc.rect(0,0,locRect.width, locRect.height); - else - texRect = locRect; - locElement = this._gafGenerateTintImage(node.texture._htmlElementObj, texRect, cacheTextureForColor, this._tintOffset, locRect); - locTexture = new cc.Texture2D(); - locTexture.initWithElement(locElement); - locTexture.handleLoadedTexture(); - node.texture = locTexture; - this._colorized = true; - } - } - - - }; - - proto._gafGenerateTintImage = function(texture, texRect, tintedImgCache, color, rect, renderCanvas){ - if (!rect) - rect = cc.rect(0, 0, texture.width, texture.height); - - // Create a new buffer if required - var w = Math.min(rect.width, tintedImgCache[0].width); - var h = Math.min(rect.height, tintedImgCache[0].height); - var buff = renderCanvas, ctx; - if (!buff) { - buff = document.createElement("canvas"); - buff.width = w; - buff.height = h; - ctx = buff.getContext("2d"); - } else { - ctx = buff.getContext("2d"); - ctx.clearRect(0, 0, w, h); - } - ctx.save(); - - // draw a channel with alpha of the original image - ctx.globalCompositeOperation = 'source-over'; - //ctx.globalAlpha = 1; - ctx.drawImage(tintedImgCache[2], rect.x, rect.y, w, h, 0, 0, w, h); - - // draw a rect of specified color - ctx.globalCompositeOperation = 'source-in'; - ctx.fillStyle = 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',1)'; - ctx.fillRect(0, 0, w, h); - - // add the desired image to the drawn - ctx.globalCompositeOperation = 'lighter'; - ctx.drawImage(texture, texRect.x, texRect.y, w, h, 0, 0, w, h); - - - ctx.restore(); - return buff; - - }; - } - -})(); diff --git a/external/gaf/Library/GAFSpriteProto.js b/external/gaf/Library/GAFSpriteProto.js index 6e33fa7d5f..e69de29bb2 100644 --- a/external/gaf/Library/GAFSpriteProto.js +++ b/external/gaf/Library/GAFSpriteProto.js @@ -1,36 +0,0 @@ - -gaf._SpriteProto = function(asset, atlasFrames, elementAtlasIdRef) -{ - //this._anchor = atlasFrame._gafAnchor; - //delete atlasFrame._gafAnchor; - - this.getFrames = function(){return atlasFrames}; - this.getIdRef = function(){return elementAtlasIdRef}; - //this.getAnchor = function() {return this._anchor}; - this.getAsset = function() {return asset}; - - /* - * Will construct GAFSprite - */ - this._gafConstruct = function() - { - var usedScale = this.getAsset()._usedAtlasScale; - var ret = new gaf.Sprite(this, usedScale); - ret._init(); - return ret; - }; -}; - -gaf._SpriteProto.prototype.getFrame = function() -{ - var usedScale = this.getAsset()._usedAtlasScale; - cc.assert(usedScale, "Error. Atlas scale zero."); - var frames = this.getFrames()[usedScale]; - cc.assert(frames, "Error. No frames found for used scale `"+usedScale+"`"); - return frames[this.getIdRef()]; -}; - -gaf._SpriteProto.prototype.getAnchor = function() -{ - return this.getFrame()._gafAnchor; -}; diff --git a/external/gaf/Library/GAFSpriteWebGLRenderCmd.js b/external/gaf/Library/GAFSpriteWebGLRenderCmd.js index eabe25b0c9..e69de29bb2 100644 --- a/external/gaf/Library/GAFSpriteWebGLRenderCmd.js +++ b/external/gaf/Library/GAFSpriteWebGLRenderCmd.js @@ -1,132 +0,0 @@ - -(function(){ - gaf.Sprite.WebGLRenderCmd = function (renderable) { - cc.Sprite.WebGLRenderCmd.call(this, renderable); - this._defualtShader = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLOR); - this._customShader = gaf._Shaders.Alpha; - - //this._shaderProgram = this._defualtShader; - - this._tintMult = null; - this._tintOffset = null; - this._ctxMatrixBody = null; - this._ctxMatrixAppendix = null; - }; - - var proto = gaf.Sprite.WebGLRenderCmd.prototype = Object.create(cc.Sprite.WebGLRenderCmd.prototype); - proto.constructor = gaf.Sprite.WebGLRenderCmd; - - proto._identityVec = [1.0, 1.0, 1.0, 1.0]; - proto._zeroVec = [0.0, 0.0, 0.0, 0.0]; - proto._identityMat = [ - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - ]; - - proto._disableCtx = function(){ - this.setShaderProgram(this._defualtShader); - }; - - proto._enableCtx = function(){ - this.setShaderProgram(this._customShader); - }; - - proto._applyCtxState = function(gafObject){ - var tintMult = gafObject._cascadeColorMult; - this._tintMult = [ - tintMult.r / 255, - tintMult.g / 255, - tintMult.b / 255, - tintMult.a / 255 - ]; - - var tintOffset = gafObject._cascadeColorOffset; - this._tintOffset = [ - tintOffset.r / 255, - tintOffset.g / 255, - tintOffset.b / 255, - tintOffset.a / 255 - ]; - - var filterStack = gafObject._filterStack; - if(filterStack && filterStack.length > 0 && filterStack[0].type === gaf.EFFECT_COLOR_MATRIX) - { - var m = filterStack[0].colorMatrix; - this._ctxMatrixBody = [ - m.rr, m.rg, m.rb, m.ra, - m.gr, m.gg, m.gb, m.ga, - m.br, m.bg, m.bb, m.ba, - m.ar, m.ag, m.ab, m.aa - ]; - this._ctxMatrixAppendix = [ - m.r / 255, - m.g / 255, - m.b / 255, - m.a / 255 - ]; - } - else - { - this._ctxMatrixBody = null; - this._ctxMatrixAppendix = null; - } - }; - - proto._setUniforms = function() - { - if(this._shaderProgram === this._customShader) - { - this._shaderProgram.use(); - { - this._shaderProgram.setUniformLocationWith4fv( - gaf._Uniforms.ColorTransformMult, - this._tintMult, - 1 - ); - this._shaderProgram.setUniformLocationWith4fv( - gaf._Uniforms.ColorTransformOffset, - this._tintOffset, - 1 - ); - } - - if(this._ctxMatrixBody && this._ctxMatrixAppendix) - { - this._shaderProgram.setUniformLocationWithMatrix4fv( - gaf._Uniforms.ColorMatrixBody, - this._ctxMatrixBody, - 1 - ); - this._shaderProgram.setUniformLocationWith4fv( - gaf._Uniforms.ColorMatrixAppendix, - this._ctxMatrixAppendix, - 1 - ); - } - else - { - this._shaderProgram.setUniformLocationWithMatrix4fv( - gaf._Uniforms.ColorMatrixBody, - this._identityMat, - 1 - ); - this._shaderProgram.setUniformLocationWith4fv( - gaf._Uniforms.ColorMatrixAppendix, - this._zeroVec, - 1 - ); - } - } - }; - - proto.rendering = function(ctx) - { - this._setUniforms(); - - // Super call - cc.Sprite.WebGLRenderCmd.prototype.rendering.call(this, ctx); - }; - -})(); diff --git a/external/gaf/Library/GAFTags.js b/external/gaf/Library/GAFTags.js index 09f8186538..e69de29bb2 100644 --- a/external/gaf/Library/GAFTags.js +++ b/external/gaf/Library/GAFTags.js @@ -1,378 +0,0 @@ - -gaf.ReadSingleTag = function(stream){ - var tagId = stream.Ushort(); - var tag = gaf.Tags[tagId]; - var result = {}; - if(typeof tag === "undefined"){ - console.log("GAF. Non implemented tag detected."); - gaf.Tags.Default.parse(stream, tagId); - } - else{ - //console.log("tag " + tag.tagName); - result = tag.parse(stream, tagId); - } - return result; -}; - -gaf.ReadTags = function(stream){ - var tags = []; - try { - do { - var tag = gaf.ReadSingleTag(stream); - tags.push(tag); - } while (tag.tagId != 0); - } - catch (e){ - if (e instanceof Error && e.message == "GAF format error"){ - console.log("GAF format error:\n" + e.stack); - // Tag will be closed and parser will continue from where it should. - } - else{ - console.log(e.stack); - throw e; - } - } - return tags; -}; - - -gaf.Tag = function(){ - this.Default = Object.create(gaf.Tag.base); - this["0"] = Object.create(gaf.Tag.End); - this["1"] = Object.create(gaf.Tag.DefineAtlas); - this["2"] = Object.create(gaf.Tag.DefineAnimationMasks); - this["3"] = Object.create(gaf.Tag.DefineAnimationObjects); - this["4"] = Object.create(gaf.Tag.DefineAnimationFrames); - this["5"] = Object.create(gaf.Tag.DefineNamedParts); - this["6"] = Object.create(gaf.Tag.DefineSequences); - this["7"] = Object.create(gaf.Tag.DefineTextFields); - this["8"] = Object.create(gaf.Tag.DefineAtlas2); - this["9"] = Object.create(gaf.Tag.DefineStage); - this["10"] = Object.create(gaf.Tag.DefineAnimationObjects2); - this["11"] = Object.create(gaf.Tag.DefineAnimationMasks2); - this["12"] = Object.create(gaf.Tag.DefineAnimationFrames2); - this["13"] = Object.create(gaf.Tag.DefineTimeline); -}; - -gaf.Tag.base = function() {}; -gaf.Tag.base.parse = function(stream, tagId){ - var size = stream.Uint(); - - stream.startNestedBuffer(size); - var result = this.doParse(stream); - stream.endNestedBuffer(); - - result.tagName = this.tagName; - result.tagId = tagId; - return result; -}; -gaf.Tag.base.doParse = function(stream){ - return {}; - }; - -gaf.Tag.End = Object.create(gaf.Tag.base); -gaf.Tag.End.tagName = "TagEnd"; - -gaf.Tag.DefineAtlas = Object.create(gaf.Tag.base); -gaf.Tag.DefineAtlas.tagName = "TagDefineAtlas"; -gaf.Tag.DefineAtlas.doParse = function (s) { - var exec = s.fields( - 'scale', 'Float', - 'atlases', s.array('Ubyte', s.fields( - 'id', 'Uint', - 'sources', s.array('Ubyte', s.fields( - 'source', 'String', - 'csf', 'Float' - )) - )), - 'elements', s.array('Uint', s.fields( - 'pivot', 'Point', - 'origin', 'Point', - 'scale', 'Float', - 'size', 'Point', - 'atlasId', 'Uint', - 'elementAtlasId', 'Uint' - )) - ); - return {'content': exec()}; -}; - -gaf.Tag.DefineAnimationMasks = Object.create(gaf.Tag.base); -gaf.Tag.DefineAnimationMasks.tagName = "TagDefineAnimationMasks"; -gaf.Tag.DefineAnimationMasks.doParse = function (s) { - var exec = s.array('Uint', s.fields( - 'objectId', 'Uint', - 'elementAtlasIdRef', 'Uint' - )); - var result = {'content': exec()}; - debugger; - return result; -}; - -gaf.Tag.DefineAnimationObjects = Object.create(gaf.Tag.base); -gaf.Tag.DefineAnimationObjects.tagName = "TagDefineAnimationObjects"; -gaf.Tag.DefineAnimationObjects.doParse = function (s) { - var exec = s.array('Uint', s.fields( - 'objectId', 'Uint', - 'elementAtlasIdRef', 'Uint' - )); - return {'content': exec()}; -}; - -gaf.Tag.DefineAnimationFrames = Object.create(gaf.Tag.base); -gaf.Tag.DefineAnimationFrames.tagName = "TagDefineAnimationFrames"; -gaf.Tag.DefineAnimationFrames.doParse = function(s){ - var exec = s.array('Uint', s.fields( - 'frame', 'Uint', - 'state', s.array('Uint', s.fields( - 'hasColorTransform', 'Ubyte', - 'hasMask', 'Ubyte', - 'hasEffect', 'Ubyte', - 'objectIdRef', 'Uint', - 'depth', 'Int', - 'alpha', 'Float', - 'matrix', 'Matrix', - 'colorTransform', s.condition('hasColorTransform', 1, s.fields( - 'alphaOffset', 'Float', - 'redMultiplier', 'Float', - 'redOffset', 'Float', - 'greenMultiplier', 'Float', - 'greenOffset', 'Float', - 'blueMultiplier', 'Float', - 'blueOffset', 'Float' - )), - 'effect', s.condition('hasEffect', 1, s.array('Ubyte', gaf.Tag._readFilter(s))), - 'maskObjectIdRef', s.condition('hasMask', 1, s.fields( - 'maskObjectIdRef', 'Uint' - )) - )) - )); - return {'content': exec()}; -}; - -gaf.Tag.DefineNamedParts = Object.create(gaf.Tag.base); -gaf.Tag.DefineNamedParts.tagName = "TagDefineNamedParts"; -gaf.Tag.DefineNamedParts.doParse = function(s) { - var exec = s.array('Uint', s.fields( - 'objectId', 'Uint', - 'name', 'String' - )); - return {'content': exec()}; -}; - -gaf.Tag.DefineSequences = Object.create(gaf.Tag.base); -gaf.Tag.DefineSequences.tagName = "TagDefineSequences"; -gaf.Tag.DefineSequences.doParse = function(s) { - var exec = s.array('Uint', s.fields( - 'id', 'String', - 'start', 'Ushort', - 'end', 'Ushort' - )); - return {'content': exec()}; -}; - -gaf.Tag.DefineTextFields = Object.create(gaf.Tag.base); -gaf.Tag.DefineTextFields.tagName = "TagDefineTextFields"; -gaf.Tag.DefineTextFields.doParse = function(s) { - var exec = s.array('Uint', s.fields( - 'id', 'Uint', - 'pivot', 'Point', - 'end', 'Ushort', - 'width', 'Float', - 'height', 'Float', - 'text', 'String', - 'embedFonts', 'Boolean', - 'multiline', 'Boolean', - 'wordWrap', 'Boolean', - 'hasRestrict', 'Boolean', - 'restrict', s.condition('hasRestrict', 1, function (){return s['String'];}), - 'editable', 'Boolean', - 'selectable', 'Boolean', - 'displayAsPassword', 'Boolean', - 'maxChars', 'Uint', - 'align', 'Uint', - 'blockIndent', 'Uint', - 'bold', 'Boolean', - 'bullet', 'Boolean', - 'color', 'color', - 'font', 'String', - 'indent', 'Uint', - 'italic', 'Boolean', - 'kerning', 'Boolean', - 'leading', 'Uint', - 'leftMargin', 'Uint', - 'letterSpacing', 'Float', - 'rightMargin', 'Uint', - 'size', 'Uint', - 'tabStops', s.array('Uint', s.fields( - 'value', 'Uint' - )), - 'target', 'string', - 'underline', 'Boolean', - 'url', 'String' - )); - return {'content': exec()}; -}; - -gaf.Tag.DefineAtlas2 = Object.create(gaf.Tag.base); -gaf.Tag.DefineAtlas2.tagName = "TagDefineAtlas2"; -gaf.Tag.DefineAtlas2.doParse = function(s) { - var exec = s.fields( - 'scale', 'Float', - 'atlases', s.array('Ubyte', s.fields( - 'id', 'Uint', - 'sources', s.array('Ubyte', s.fields( - 'source', 'String', - 'csf', 'Float' - )) - )), - 'elements', s.array('Uint', s.fields( - 'pivot', 'Point', - 'origin', 'Point', - 'scale', 'Float', - 'size', 'Point', - 'atlasId', 'Uint', - 'elementAtlasId', 'Uint', - 'hasScale9Grid', 'Boolean', - 'scale9GridRect', s.condition('hasScale9Grid', 1, function(){return s.Rect();}) - )) - ); - return {'content': exec()}; -}; - -gaf.Tag.DefineStage = Object.create(gaf.Tag.base); -gaf.Tag.DefineStage.tagName = "TagDefineStage"; -gaf.Tag.DefineStage.doParse = function(s) { - var exec = s.fields( - 'fps', 'Ubyte', - 'color', 'color', - 'width', 'Ushort', - 'height', 'Ushort' - ); - return {'content': exec()}; -}; - -gaf.Tag.DefineAnimationObjects2 = Object.create(gaf.Tag.base); -gaf.Tag.DefineAnimationObjects2.tagName = "TagDefineAnimationObjects2"; -gaf.Tag.DefineAnimationObjects2.doParse = function(s) { - var exec = s.array('Uint', s.fields( - 'objectId', 'Uint', - 'elementAtlasIdRef', 'Uint', - 'type', 'Ushort' - )); - return {'content': exec()}; -}; - -gaf.Tag.DefineAnimationMasks2 = Object.create(gaf.Tag.base); -gaf.Tag.DefineAnimationMasks2.tagName = "TagDefineAnimationMasks2"; -gaf.Tag.DefineAnimationMasks2.doParse = function(s) { - var exec = s.array('Uint', s.fields( - 'objectId', 'Uint', - 'elementAtlasIdRef', 'Uint', - 'type', 'Ushort' - )); - return {'content': exec()}; -}; - -gaf.Tag.DefineAnimationFrames2 = Object.create(gaf.Tag.base); -gaf.Tag.DefineAnimationFrames2.tagName = "TagDefineAnimationFrames2"; -gaf.Tag.DefineAnimationFrames2.doParse = function(s) { - var exec = s.array('Uint', s.fields( - 'frame', 'Uint', - 'hasChangesInDisplayList', 'Boolean', - 'hasActions', 'Boolean', - 'state', s.condition('hasChangesInDisplayList', 1, s.array('Uint', s.fields( - 'hasColorTransform', 'Boolean', - 'hasMask', 'Boolean', - 'hasEffect', 'Boolean', - 'objectIdRef', 'Uint', - 'depth', 'Int', - 'alpha', 'Float', - 'matrix', 'Matrix', - 'colorTransform', s.condition('hasColorTransform', 1, s.fields( - 'alphaOffset', 'Float', - 'redMultiplier', 'Float', - 'redOffset', 'Float', - 'greenMultiplier', 'Float', - 'greenOffset', 'Float', - 'blueMultiplier', 'Float', - 'blueOffset', 'Float' - )), - 'effect', s.condition('hasEffect', 1, s.array('Ubyte', gaf.Tag._readFilter(s))), - 'maskObjectIdRef', s.condition('hasMask', 1, function(){return s.Uint()}) - ))), - 'actions', s.condition('hasActions', 1, s.array('Uint', s.fields( - 'type', 'Uint', - 'scope', 'String', - 'params', gaf.Tag._readActionArguments(s) - ))) - )); - return {'content': exec()}; -}; - -gaf.Tag.DefineTimeline = Object.create(gaf.Tag.base); -gaf.Tag.DefineTimeline.tagName = "TagDefineTimeline"; -gaf.Tag.DefineTimeline.doParse = function(s) { - var exec = s.fields( - 'id', 'Uint', - 'animationFrameCount', 'Uint', - 'boundingBox', 'Rect', - 'pivotPoint', 'Point', - 'hasLinkage', 'Boolean', - 'linkageName', s.condition('hasLinkage', 1, function () { - return s.String(); - }) - ); - var result = {'content': exec()}; - result.content.tags = gaf.ReadTags(s); - return result; -}; - -gaf.Tag._readActionArguments = function(s){ - return function(){ - var size = s.Uint(); - var ret = []; - s.startNestedBuffer(size); - while(s.maxOffset() < s.tell()){ - ret.push(s.String()); - } - s.endNestedBuffer(); - return ret; - }; -}; - -gaf.Tag._readFilter = function(s){ - return s.fields( - 'type', 'Uint', - 'dropShadow', s.condition('type', gaf.EFFECT_DROP_SHADOW, s.fields( // DropShadow - 'color', 'color', - 'blurX', 'Float', - 'blurY', 'Float', - 'angle', 'Float', - 'distance', 'Float', - 'strength', 'Float', - 'inner', 'Boolean', - 'knockout', 'Boolean' - )), - 'blur', s.condition('type', gaf.EFFECT_BLUR, s.fields( // Blur - 'blurX', 'Float', - 'blurY', 'Float' - )), - 'glow', s.condition('type', gaf.EFFECT_GLOW, s.fields( // Glow - 'color', 'color', - 'blurX', 'Float', - 'blurY', 'Float', - 'strength', 'Float', - 'inner', 'Boolean', - 'knockout', 'Boolean' - )), - 'colorMatrix', s.condition('type', gaf.EFFECT_COLOR_MATRIX, s.fields( // ColorMatrix - 'rr', 'Float', 'gr', 'Float', 'br', 'Float', 'ar', 'Float', 'r', 'Float', - 'rg', 'Float', 'gg', 'Float', 'bg', 'Float', 'ag', 'Float', 'g', 'Float', - 'rb', 'Float', 'gb', 'Float', 'bb', 'Float', 'ab', 'Float', 'b', 'Float', - 'ra', 'Float', 'ga', 'Float', 'ba', 'Float', 'aa', 'Float', 'a', 'Float' - )) - ) -}; - -gaf.Tags = new gaf.Tag(); diff --git a/external/gaf/Library/GAFTextField.js b/external/gaf/Library/GAFTextField.js index 04f9744920..e69de29bb2 100644 --- a/external/gaf/Library/GAFTextField.js +++ b/external/gaf/Library/GAFTextField.js @@ -1,6 +0,0 @@ - -gaf.TextField = gaf.Object.extend -({ - _className: "GAFTextField" - -}); \ No newline at end of file diff --git a/external/gaf/Library/GAFTimeLine.js b/external/gaf/Library/GAFTimeLine.js index ef9387aa46..e69de29bb2 100644 --- a/external/gaf/Library/GAFTimeLine.js +++ b/external/gaf/Library/GAFTimeLine.js @@ -1,547 +0,0 @@ - -gaf.TimeLine = gaf.Object.extend -({ - _className: "GAFTimeLine", - _objects: null, - _container: null, - _animationStartedNextLoopDelegate: null, - _animationFinishedPlayDelegate: null, - _framePlayedDelegate: null, - _sequenceDelegate: null, - _fps: 60, - _frameTime: 1/60, - _currentSequenceStart: gaf.FIRST_FRAME_INDEX, - _currentSequenceEnd: gaf.FIRST_FRAME_INDEX, - _totalFrameCount: 0, - _isRunning: false, - _isLooped: false, - _isReversed: false, - _timeDelta: 0, - _animationsSelectorScheduled: false, - _currentFrame: gaf.FIRST_FRAME_INDEX, - - - setAnimationStartedNextLoopDelegate: function (delegate) - { - this._animationStartedNextLoopDelegate = delegate; - }, - setAnimationFinishedPlayDelegate: function (delegate) - { - this._animationFinishedPlayDelegate = delegate; - }, - setLooped: function (looped, recursively) - { - this._isLooped = looped; - if (recursively) - { - this._objects.forEach(function (item) - { - item.setLooped(looped, recursively); - }); - } - }, - getBoundingBoxForCurrentFrame: function () - { - var result = null;//cc.rect(); - var isFirstObj = true; - this._objects.forEach(function (item) { - if(item.isVisibleInCurrentFrame() && item.isVisible()) - { - var bb = item.getBoundingBoxForCurrentFrame(); - if(!bb) - { - bb = item.getBoundingBox(); - } - if (isFirstObj) - { - isFirstObj = false; - result = bb; - } - else - { - result = cc.rectUnion(result, bb); - } - } - }); - return cc._rectApplyAffineTransformIn(result, this._container.getNodeToParentTransform()); - }, - setFps: function (fps) - { - cc.assert(fps !== 0, 'Error! Fps is set to zero.'); - this._fps = fps; - this._frameTime = 1/fps; - }, - getObjectByName: function (name) - { - var elements = name.split('.'); - var result = null; - var retId = -1; - var timeLine = this; - var BreakException = {}; - try - { - elements.forEach(function(element) - { - var parts = timeLine._gafproto.getNamedParts(); - if(parts.hasOwnProperty(element)) - { - retId = parts[element]; - } - else - { - // Sequence is incorrect - BreakException.lastElement = element; - throw BreakException; - } - result = timeLine._objects[retId]; - timeLine = result; - }); - } - catch (e) - { - if (e!==BreakException) - { - throw e; - } - cc.log("Sequence incorrect: `" + name + "` At: `" + BreakException.lastElement + "`"); - return null; - } - return result; - }, - clearSequence: function () - { - this._currentSequenceStart = gaf.FIRST_FRAME_INDEX; - this._currentSequenceEnd = this._gafproto.getTotalFrames(); - }, - getIsAnimationRunning: function () - { - return this._isRunning; - }, - gotoAndStop: function (value) - { - var frame = 0; - if (typeof value === 'string') - { - frame = this.getStartFrame(value); - } - else - { - frame = value; - } - if (this.setFrame(frame)) - { - this.setAnimationRunning(false, false); - return true; - } - return false; - }, - gotoAndPlay: function (value) - { - var frame = 0; - if (typeof value === 'string') - { - frame = this.getStartFrame(value); - } - else - { - frame = value; - } - if (this.setFrame(frame)) - { - this.setAnimationRunning(true, false); - return true; - } - return false; - }, - getStartFrame: function (frameLabel) - { - var seq = this._gafproto.getSequences()[frameLabel]; - if (seq) - { - return seq.start; - } - return gaf.IDNONE; - }, - getEndFrame: function (frameLabel) - { - var seq = this._gafproto.getSequences()[frameLabel]; - if (seq) - { - return seq.end; - } - return gaf.IDNONE; - }, - setFramePlayedDelegate: function (delegate) - { - this._framePlayedDelegate = delegate; - }, - getCurrentFrameIndex: function () - { - return this._showingFrame; - }, - getTotalFrameCount: function () - { - return this._gafproto.getTotalFrames(); - }, - start: function () - { - this._enableTick(true); - if (!this._isRunning) - { - this._currentFrame = gaf.FIRST_FRAME_INDEX; - this.setAnimationRunning(true, true); - } - }, - stop: function () - { - this._enableTick(false); - if (this._isRunning) - { - this._currentFrame = gaf.FIRST_FRAME_INDEX; - this.setAnimationRunning(false, true); - } - }, - isDone: function () - { - if (this._isLooped) - { - return false; - } - else - { - if (!this._isReversed) - { - return this._currentFrame > this._totalFrameCount; - } - else - { - return this._currentFrame < gaf.FIRST_FRAME_INDEX - 1; - } - } - }, - getSequences: function() - { - return this._gafproto.getSequences(); - }, - playSequence: function (name, looped) - { - var s = this.getStartFrame(name); - var e = this.getEndFrame(name); - if (gaf.IDNONE === s || gaf.IDNONE === e) - { - return false; - } - this._currentSequenceStart = s; - this._currentSequenceEnd = e; - if (this._currentFrame < this._currentSequenceStart || this._currentFrame > this._currentSequenceEnd) - { - this._currentFrame = this._currentSequenceStart; - } - else - { - this._currentFrame = this._currentSequenceStart; - } - this.setLooped(looped, false); - this.resumeAnimation(); - return true; - }, - isReversed: function () - { - return this._isReversed; - }, - setSequenceDelegate: function (delegate) - { - this._sequenceDelegate = delegate; - }, - setFrame: function (index) - { - if (index >= gaf.FIRST_FRAME_INDEX && index < this._totalFrameCount) - { - this._showingFrame = index; - this._currentFrame = index; - this._processAnimation(); - return true; - } - return false; - }, - - pauseAnimation: function () - { - if (this._isRunning) - { - this.setAnimationRunning(false, false); - } - }, - isLooped: function () - { - return this._isLooped; - }, - resumeAnimation: function () - { - if (!this._isRunning) - { - this.setAnimationRunning(true, false); - } - }, - setReversed: function (reversed) - { - this._isReversed = reversed; - }, - hasSequences: function () - { - return this._gafproto.getSequences().length > 0; - }, - getFps: function () - { - return this._fps; - }, - - - // Private - - ctor: function(gafTimeLineProto, scale) - { - this._super(scale); - this._objects = []; - cc.assert(gafTimeLineProto, "Error! Missing mandatory parameter."); - this._gafproto = gafTimeLineProto; - }, - - setExternalTransform: function(affineTransform) - { - if(!cc.affineTransformEqualToTransform(this._container._additionalTransform, affineTransform)) - { - this._container.setAdditionalTransform(affineTransform); - } - }, - - _init: function() - { - this.setContentSize(this._gafproto.getBoundingBox()); - this._currentSequenceEnd = this._gafproto.getTotalFrames(); - this._totalFrameCount = this._currentSequenceEnd; - this.setFps(this._gafproto.getFps()); - this._container = new cc.Node(); - this.addChild(this._container); - - var self = this; - var asset = this._gafproto.getAsset(); - - // Construct objects for current time line - this._gafproto.getObjects().forEach(function(object) - { - var objectProto = asset._getProtos()[object]; - cc.assert(objectProto, "Error. GAF proto for type: " + object.type + " and reference id: " + object + " not found."); - self._objects[object] = objectProto._gafConstruct(); - }); - }, - - _enableTick: function(val) - { - if (!this._animationsSelectorScheduled && val) - { - this.schedule(this._processAnimations); - this._animationsSelectorScheduled = true; - } - else if (this._animationsSelectorScheduled && !val) - { - this.unschedule(this._processAnimations); - this._animationsSelectorScheduled = false; - } - }, - - _processAnimations: function (dt) - { - this._timeDelta += dt; - while (this._timeDelta >= this._frameTime) - { - this._timeDelta -= this._frameTime; - this._step(); - } - }, - - _step: function () - { - this._showingFrame = this._currentFrame; - - if(!this.getIsAnimationRunning()) - { - this._processAnimation(); - return; - } - - if(this._sequenceDelegate) - { - var seq; - if(!this._isReversed) - { - seq = this._getSequenceByLastFrame(this._currentFrame); - } - else - { - seq = this._getSequenceByFirstFrame(this._currentFrame + 1); - } - - if (seq) - { - this._sequenceDelegate(this, seq); - } - } - if (this._isCurrentFrameLastInSequence()) - { - if(this._isLooped) - { - if(this._animationStartedNextLoopDelegate) - this._animationStartedNextLoopDelegate(this); - } - else - { - this.setAnimationRunning(false, false); - if(this._animationFinishedPlayDelegate) - this._animationFinishedPlayDelegate(this); - } - } - this._processAnimation(); - this._currentFrame = this._nextFrame(); - }, - - _isCurrentFrameLastInSequence: function() - { - if (this._isReversed) - return this._currentFrame == this._currentSequenceStart; - return this._currentFrame == this._currentSequenceEnd - 1; - }, - - _nextFrame: function() - { - if (this._isCurrentFrameLastInSequence()) - { - if (!this._isLooped) - return this._currentFrame; - - if (this._isReversed) - return this._currentSequenceEnd - 1; - else - return this._currentSequenceStart; - } - - return this._currentFrame + (this._isReversed ? -1 : 1); - }, - - _processAnimation: function () - { - //var id = this._gafproto.getId(); - this._realizeFrame(this._container, this._currentFrame); - if (this._framePlayedDelegate) - { - this._framePlayedDelegate(this, this._currentFrame); - } - }, - _realizeFrame: function(out, frameIndex) - { - var self = this; - var objects = self._objects; - var frames = self._gafproto.getFrames(); - if(frameIndex > frames.length) - { - return; - } - var currentFrame = frames[frameIndex]; - if(!currentFrame) - { - return; - } - var states = currentFrame.states; - for(var stateIdx = 0, total = states.length; stateIdx < total; ++stateIdx) - { - var state = states[stateIdx]; - var object = objects[state.objectIdRef]; - if(!object) - { - return; - } - if(state.alpha < 0) - { - object._resetState(); - } - object._updateVisibility(state, self); - if(!object.isVisible()) - { - continue; - } - object._applyState(state, self); - var parent = out; - if(state.hasMask) - { - parent = objects[state.maskObjectIdRef]._getNode(); - cc.assert(parent, "Error! Mask not found."); - } - object._lastVisibleInFrame = 1 + frameIndex; - gaf.TimeLine.rearrangeSubobject(parent, object, state.depth); - if(object._step) - { - object._step(); - } - } - }, - setAnimationRunning: function (value, recursively) - { - this._isRunning = value; - if(recursively) - { - this._objects.forEach(function (obj) - { - if (obj && obj.setAnimationRunning) - { - obj.setAnimationRunning(value, recursively); - } - }); - } - }, - - _getSequenceByLastFrame: function(){ - var sequences = this._gafproto.getSequences(); - for(var item in sequences){ - if(sequences.hasOwnProperty(item)){ - if(sequences[item].end === frame + 1) - { - return item; - } - } - } - return ""; - }, - - _resetState : function() - { - this._super(); - this._currentFrame = this._currentSequenceStart; - }, - - _getSequenceByFirstFrame: function(){ - var sequences = this._gafproto.getSequences(); - for(var item in sequences){ - if(sequences.hasOwnProperty(item)){ - if(sequences[item].start === frame) - { - return item; - } - } - } - return ""; - } -}); - -gaf.TimeLine.rearrangeSubobject = function(out, object, depth) -{ - var parent = object.getParent(); - if (parent !== out) - { - object.removeFromParent(false); - out.addChild(object, depth); - } - else - { - object.setLocalZOrder(depth); - } -}; diff --git a/external/gaf/Library/GAFTimeLineProto.js b/external/gaf/Library/GAFTimeLineProto.js index 9d78b219d9..e69de29bb2 100644 --- a/external/gaf/Library/GAFTimeLineProto.js +++ b/external/gaf/Library/GAFTimeLineProto.js @@ -1,32 +0,0 @@ - -gaf._TimeLineProto = function(asset, animationFrameCount, boundingBox, pivotPoint, id, linkageName) -{ - id = typeof id != 'undefined' ? id : 0; - linkageName = linkageName || ""; - - this._objects = []; - - this.getTotalFrames = function(){return animationFrameCount}; - this.getBoundingBox = function() {return boundingBox}; - this.getId = function() {return id}; - this.getLinkageName = function() {return linkageName}; - this.getPivot = function(){return pivotPoint}; - this.getRect = function(){return boundingBox}; - this.getNamedParts = function() {return {}}; // Map name -> id - this.getSequences = function() {return {}}; // Map name -> {start, end} - this.getFrames = function(){return []}; // Array {states, actions} - this.getFps = function(){return 60}; - this.getObjects = function(){return this._objects}; - this.getAsset = function(){return asset}; - - /* - * Will construct GAFTimeLine - */ - this._gafConstruct = function() - { - var usedScale = this.getAsset()._usedAtlasScale; - var ret = new gaf.TimeLine(this, usedScale); - ret._init(); - return ret; - }; -}; diff --git a/external/gaf/gaf_viewer.js b/external/gaf/gaf_viewer.js index db5bdbea7f..e69de29bb2 100644 --- a/external/gaf/gaf_viewer.js +++ b/external/gaf/gaf_viewer.js @@ -1,219 +0,0 @@ - /* - * Created by Teivaz on 29.11.2014. - * Thanks to David Caldwell for `renderjson` - */ -function handleFileSelect(evt) { - evt.stopPropagation(); - evt.preventDefault(); - - var files = evt.dataTransfer.files; - - var output = []; - for (var i = 0, f; f = files[i]; i++) { - var name = escape(f.name); - var ext = name.split('.').pop(); - if (ext == 'gaf') { - var reader = new FileReader(); - reader.onload = (function(theFile) { - return function(req) { - var arrayBuffer = new gaf.DataReader(req.target.result); - var loader = new gaf.Loader(); - var data = loader.LoadStream(arrayBuffer); - document.getElementById('list').appendChild(renderjson(data)); - }; - })(f); - reader.readAsArrayBuffer(f); - } - } -} - -function handleDragOver(evt) { - evt.stopPropagation(); - evt.preventDefault(); - evt.dataTransfer.dropEffect = 'copy'; -} - -var dropZone = document.getElementById('drop_zone'); -dropZone.addEventListener('dragover', handleDragOver, false); -dropZone.addEventListener('drop', handleFileSelect, false); - -var module; -(module || {}).exports = renderjson = (function() { - var themetext = function( /* [class, text]+ */ ) { - var spans = []; - while (arguments.length) - spans.push(append(span(Array.prototype.shift.call(arguments)), - text(Array.prototype.shift.call(arguments)))); - return spans; - }; - var append = function( /* el, ... */ ) { - var el = Array.prototype.shift.call(arguments); - for (var a = 0; a < arguments.length; a++) - if (arguments[a].constructor == Array) - append.apply(this, [el].concat(arguments[a])); - else - el.appendChild(arguments[a]); - return el; - }; - var prepend = function(el, child) { - el.insertBefore(child, el.firstChild); - return el; - }; - var isempty = function(obj) { - for (var k in obj) - if (obj.hasOwnProperty(k)) return false; - return true; - }; - var text = function(txt) { - return document.createTextNode(txt) - }; - var div = function() { - return document.createElement("div") - }; - var span = function(classname) { - var s = document.createElement("span"); - if (classname) s.className = classname; - return s; - }; - var A = function A(txt, classname, callback) { - var a = document.createElement("a"); - if (classname) a.className = classname; - a.appendChild(text(txt)); - a.href = '#'; - a.onclick = function() { - callback(); - return false; - }; - return a; - }; - - function _renderjson(json, indent, dont_indent, show_level, sort_objects) { - var my_indent = dont_indent ? "" : indent; - - if (json === null) return themetext(null, my_indent, "keyword", "null"); - if (json === void 0) return themetext(null, my_indent, "keyword", "undefined"); - if (typeof(json) != "object") // Strings, numbers and bools - return themetext(null, my_indent, typeof(json), JSON.stringify(json)); - - var disclosure = function(open, close, type, builder) { - var content; - var empty = span(type); - var show = function() { - if (!content) append(empty.parentNode, - content = prepend(builder(), - A(renderjson.hide, "disclosure", - function() { - content.style.display = "none"; - empty.style.display = "inline"; - }))); - content.style.display = "inline"; - empty.style.display = "none"; - }; - - function isColor(a){ - return a.hasOwnProperty('a') && a.hasOwnProperty('r') && a.hasOwnProperty('g') && a.hasOwnProperty('b'); - } - - var color_rect = span(); - if (json.hasOwnProperty("tagName")) - var placeholder = json.tagName; - else if (json.hasOwnProperty("header")) - placeholder = " GAF v" + json.header.versionMajor + "." + json.header.versionMinor + " "; - else if (json.constructor == Array) - placeholder = " " + json.length + " "; - else if (json.hasOwnProperty("id")) - placeholder = " id:" + json.id + " ... "; - else if (json.hasOwnProperty("objectId")) - placeholder = " id:" + json.objectId + " ... "; - else if (json.hasOwnProperty("frame")) - placeholder = " frame:" + json.frame + " ... "; - else if(isColor(json)){ - color_rect.style.backgroundColor = "rgba("+json.r+","+json.g+","+json.b+","+json.a / 255.0+")";// parseInt(json.r).toString(16) + parseInt(json.g).toString(16) + parseInt(json.b).toString(16); - color_rect.style.height = '10px'; - color_rect.style.width = '10px'; - color_rect.style.display = 'inline-block'; - color_rect.style.margin = '0 4px'; - color_rect.style.border = '1px solid #7f7f7f'; - } - - placeholder = placeholder || ' ... '; - append(empty, - A(renderjson.show, "disclosure", show), - color_rect, - themetext(type + " syntax", open), - A(placeholder, null, show), - themetext(type + " syntax", close)); - - var el = append(span(), text(my_indent.slice(0, -1)), empty); - if (show_level > 0) - show(); - return el; - }; - - if (json.constructor == Array) { - if (json.length == 0) return themetext(null, my_indent, "array syntax", "[]"); - - return disclosure("[", "]", "array", function() { - var as = append(span("array"), themetext("array syntax", "[", null, "\n")); - for (var i = 0; i < json.length; i++) - append(as, - _renderjson(json[i], indent + " ", false, show_level - 1, sort_objects), - i != json.length - 1 ? themetext("syntax", ",") : [], - text("\n")); - append(as, themetext(null, indent, "array syntax", "]")); - return as; - }); - } - - // object - if (isempty(json)) - return themetext(null, my_indent, "object syntax", "{}"); - - - return disclosure("{", "}", "object", function() { - var os = append(span("object"), themetext("object syntax", "{", null, "\n")); - for (var k in json) var last = k; - var keys = Object.keys(json); - if (sort_objects) - keys = keys.sort(); - for (var i in keys) { - var k = keys[i]; - append(os, themetext(null, indent + " ", "key", '"' + k + '"', "object syntax", ': '), - _renderjson(json[k], indent + " ", true, show_level - 1, sort_objects), - k != last ? themetext("syntax", ",") : [], - text("\n")); - } - append(os, themetext(null, indent, "object syntax", "}")); - return os; - }); - } - - var renderjson = function renderjson(json) { - var pre = append(document.createElement("pre"), _renderjson(json, "", false, renderjson.show_to_level, renderjson.sort_objects)); - pre.className = "renderjson"; - return pre; - }; - renderjson.set_icons = function(show, hide) { - renderjson.show = show; - renderjson.hide = hide; - return renderjson; - }; - renderjson.set_show_to_level = function(level) { - renderjson.show_to_level = typeof level == "string" && - level.toLowerCase() === "all" ? Number.MAX_VALUE : level; - return renderjson; - }; - renderjson.set_sort_objects = function(sort_bool) { - renderjson.sort_objects = sort_bool; - return renderjson; - }; - // Backwards compatiblity. Use set_show_to_level() for new code. - renderjson.set_show_by_default = function(show) { - renderjson.show_to_level = show ? Number.MAX_VALUE : 0; - return renderjson; - }; - renderjson.set_icons('⊕', '⊖'); - renderjson.set_show_by_default(false); - renderjson.set_sort_objects(false); - return renderjson; -})(); \ No newline at end of file diff --git a/external/socketio/socket.io.js b/external/socketio/socket.io.js index 16caccfc1d..e69de29bb2 100644 --- a/external/socketio/socket.io.js +++ b/external/socketio/socket.io.js @@ -1,7000 +0,0 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.io=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0 && !this.encoding) { - var pack = this.packetBuffer.shift(); - this.packet(pack); - } - }; - - /** - * Clean up transport subscriptions and packet buffer. - * - * @api private - */ - - Manager.prototype.cleanup = function(){ - var sub; - while (sub = this.subs.shift()) sub.destroy(); - - this.packetBuffer = []; - this.encoding = false; - - this.decoder.destroy(); - }; - - /** - * Close the current socket. - * - * @api private - */ - - Manager.prototype.close = - Manager.prototype.disconnect = function(){ - this.skipReconnect = true; - this.backoff.reset(); - this.readyState = 'closed'; - this.engine && this.engine.close(); - }; - - /** - * Called upon engine close. - * - * @api private - */ - - Manager.prototype.onclose = function(reason){ - debug('close'); - this.cleanup(); - this.backoff.reset(); - this.readyState = 'closed'; - this.emit('close', reason); - if (this._reconnection && !this.skipReconnect) { - this.reconnect(); - } - }; - - /** - * Attempt a reconnection. - * - * @api private - */ - - Manager.prototype.reconnect = function(){ - if (this.reconnecting || this.skipReconnect) return this; - - var self = this; - - if (this.backoff.attempts >= this._reconnectionAttempts) { - debug('reconnect failed'); - this.backoff.reset(); - this.emitAll('reconnect_failed'); - this.reconnecting = false; - } else { - var delay = this.backoff.duration(); - debug('will wait %dms before reconnect attempt', delay); - - this.reconnecting = true; - var timer = setTimeout(function(){ - if (self.skipReconnect) return; - - debug('attempting reconnect'); - self.emitAll('reconnect_attempt', self.backoff.attempts); - self.emitAll('reconnecting', self.backoff.attempts); - - // check again for the case socket closed in above events - if (self.skipReconnect) return; - - self.open(function(err){ - if (err) { - debug('reconnect attempt error'); - self.reconnecting = false; - self.reconnect(); - self.emitAll('reconnect_error', err.data); - } else { - debug('reconnect success'); - self.onreconnect(); - } - }); - }, delay); - - this.subs.push({ - destroy: function(){ - clearTimeout(timer); - } - }); - } - }; - - /** - * Called upon successful reconnect. - * - * @api private - */ - - Manager.prototype.onreconnect = function(){ - var attempt = this.backoff.attempts; - this.reconnecting = false; - this.backoff.reset(); - this.updateSocketIds(); - this.emitAll('reconnect', attempt); - }; - -},{"./on":4,"./socket":5,"./url":6,"backo2":7,"component-bind":8,"component-emitter":9,"debug":10,"engine.io-client":11,"indexof":42,"object-component":43,"socket.io-parser":46}],4:[function(_dereq_,module,exports){ - - /** - * Module exports. - */ - - module.exports = on; - - /** - * Helper for subscriptions. - * - * @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter` - * @param {String} event name - * @param {Function} callback - * @api public - */ - - function on(obj, ev, fn) { - obj.on(ev, fn); - return { - destroy: function(){ - obj.removeListener(ev, fn); - } - }; - } - -},{}],5:[function(_dereq_,module,exports){ - - /** - * Module dependencies. - */ - - var parser = _dereq_('socket.io-parser'); - var Emitter = _dereq_('component-emitter'); - var toArray = _dereq_('to-array'); - var on = _dereq_('./on'); - var bind = _dereq_('component-bind'); - var debug = _dereq_('debug')('socket.io-client:socket'); - var hasBin = _dereq_('has-binary'); - - /** - * Module exports. - */ - - module.exports = exports = Socket; - - /** - * Internal events (blacklisted). - * These events can't be emitted by the user. - * - * @api private - */ - - var events = { - connect: 1, - connect_error: 1, - connect_timeout: 1, - disconnect: 1, - error: 1, - reconnect: 1, - reconnect_attempt: 1, - reconnect_failed: 1, - reconnect_error: 1, - reconnecting: 1 - }; - - /** - * Shortcut to `Emitter#emit`. - */ - - var emit = Emitter.prototype.emit; - - /** - * `Socket` constructor. - * - * @api public - */ - - function Socket(io, nsp){ - this.io = io; - this.nsp = nsp; - this.json = this; // compat - this.ids = 0; - this.acks = {}; - if (this.io.autoConnect) this.open(); - this.receiveBuffer = []; - this.sendBuffer = []; - this.connected = false; - this.disconnected = true; - } - - /** - * Mix in `Emitter`. - */ - - Emitter(Socket.prototype); - - /** - * Subscribe to open, close and packet events - * - * @api private - */ - - Socket.prototype.subEvents = function() { - if (this.subs) return; - - var io = this.io; - this.subs = [ - on(io, 'open', bind(this, 'onopen')), - on(io, 'packet', bind(this, 'onpacket')), - on(io, 'close', bind(this, 'onclose')) - ]; - }; - - /** - * "Opens" the socket. - * - * @api public - */ - - Socket.prototype.open = - Socket.prototype.connect = function(){ - if (this.connected) return this; - - this.subEvents(); - this.io.open(); // ensure open - if ('open' == this.io.readyState) this.onopen(); - return this; - }; - - /** - * Sends a `message` event. - * - * @return {Socket} self - * @api public - */ - - Socket.prototype.send = function(){ - var args = toArray(arguments); - args.unshift('message'); - this.emit.apply(this, args); - return this; - }; - - /** - * Override `emit`. - * If the event is in `events`, it's emitted normally. - * - * @param {String} event name - * @return {Socket} self - * @api public - */ - - Socket.prototype.emit = function(ev){ - if (events.hasOwnProperty(ev)) { - emit.apply(this, arguments); - return this; - } - - var args = toArray(arguments); - var parserType = parser.EVENT; // default - if (hasBin(args)) { parserType = parser.BINARY_EVENT; } // binary - var packet = { type: parserType, data: args }; - - // event ack callback - if ('function' == typeof args[args.length - 1]) { - debug('emitting packet with ack id %d', this.ids); - this.acks[this.ids] = args.pop(); - packet.id = this.ids++; - } - - if (this.connected) { - this.packet(packet); - } else { - this.sendBuffer.push(packet); - } - - return this; - }; - - /** - * Sends a packet. - * - * @param {Object} packet - * @api private - */ - - Socket.prototype.packet = function(packet){ - packet.nsp = this.nsp; - this.io.packet(packet); - }; - - /** - * Called upon engine `open`. - * - * @api private - */ - - Socket.prototype.onopen = function(){ - debug('transport is open - connecting'); - - // write connect packet if necessary - if ('/' != this.nsp) { - this.packet({ type: parser.CONNECT }); - } - }; - - /** - * Called upon engine `close`. - * - * @param {String} reason - * @api private - */ - - Socket.prototype.onclose = function(reason){ - debug('close (%s)', reason); - this.connected = false; - this.disconnected = true; - delete this.id; - this.emit('disconnect', reason); - }; - - /** - * Called with socket packet. - * - * @param {Object} packet - * @api private - */ - - Socket.prototype.onpacket = function(packet){ - if (packet.nsp != this.nsp) return; - - switch (packet.type) { - case parser.CONNECT: - this.onconnect(); - break; - - case parser.EVENT: - this.onevent(packet); - break; - - case parser.BINARY_EVENT: - this.onevent(packet); - break; - - case parser.ACK: - this.onack(packet); - break; - - case parser.BINARY_ACK: - this.onack(packet); - break; - - case parser.DISCONNECT: - this.ondisconnect(); - break; - - case parser.ERROR: - this.emit('error', packet.data); - break; - } - }; - - /** - * Called upon a server event. - * - * @param {Object} packet - * @api private - */ - - Socket.prototype.onevent = function(packet){ - var args = packet.data || []; - debug('emitting event %j', args); - - if (null != packet.id) { - debug('attaching ack callback to event'); - args.push(this.ack(packet.id)); - } - - if (this.connected) { - emit.apply(this, args); - } else { - this.receiveBuffer.push(args); - } - }; - - /** - * Produces an ack callback to emit with an event. - * - * @api private - */ - - Socket.prototype.ack = function(id){ - var self = this; - var sent = false; - return function(){ - // prevent double callbacks - if (sent) return; - sent = true; - var args = toArray(arguments); - debug('sending ack %j', args); - - var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK; - self.packet({ - type: type, - id: id, - data: args - }); - }; - }; - - /** - * Called upon a server acknowlegement. - * - * @param {Object} packet - * @api private - */ - - Socket.prototype.onack = function(packet){ - debug('calling ack %s with %j', packet.id, packet.data); - var fn = this.acks[packet.id]; - fn.apply(this, packet.data); - delete this.acks[packet.id]; - }; - - /** - * Called upon server connect. - * - * @api private - */ - - Socket.prototype.onconnect = function(){ - this.connected = true; - this.disconnected = false; - this.emit('connect'); - this.emitBuffered(); - }; - - /** - * Emit buffered events (received and emitted). - * - * @api private - */ - - Socket.prototype.emitBuffered = function(){ - var i; - for (i = 0; i < this.receiveBuffer.length; i++) { - emit.apply(this, this.receiveBuffer[i]); - } - this.receiveBuffer = []; - - for (i = 0; i < this.sendBuffer.length; i++) { - this.packet(this.sendBuffer[i]); - } - this.sendBuffer = []; - }; - - /** - * Called upon server disconnect. - * - * @api private - */ - - Socket.prototype.ondisconnect = function(){ - debug('server disconnect (%s)', this.nsp); - this.destroy(); - this.onclose('io server disconnect'); - }; - - /** - * Called upon forced client/server side disconnections, - * this method ensures the manager stops tracking us and - * that reconnections don't get triggered for this. - * - * @api private. - */ - - Socket.prototype.destroy = function(){ - if (this.subs) { - // clean subscriptions to avoid reconnections - for (var i = 0; i < this.subs.length; i++) { - this.subs[i].destroy(); - } - this.subs = null; - } - - this.io.destroy(this); - }; - - /** - * Disconnects the socket manually. - * - * @return {Socket} self - * @api public - */ - - Socket.prototype.close = - Socket.prototype.disconnect = function(){ - if (this.connected) { - debug('performing disconnect (%s)', this.nsp); - this.packet({ type: parser.DISCONNECT }); - } - - // remove socket from pool - this.destroy(); - - if (this.connected) { - // fire events - this.onclose('io client disconnect'); - } - return this; - }; - -},{"./on":4,"component-bind":8,"component-emitter":9,"debug":10,"has-binary":38,"socket.io-parser":46,"to-array":50}],6:[function(_dereq_,module,exports){ - (function (global){ - - /** - * Module dependencies. - */ - - var parseuri = _dereq_('parseuri'); - var debug = _dereq_('debug')('socket.io-client:url'); - - /** - * Module exports. - */ - - module.exports = url; - - /** - * URL parser. - * - * @param {String} url - * @param {Object} An object meant to mimic window.location. - * Defaults to window.location. - * @api public - */ - - function url(uri, loc){ - var obj = uri; - - // default to window.location - var loc = loc || global.location; - if (null == uri) uri = loc.protocol + '//' + loc.host; - - // relative path support - if ('string' == typeof uri) { - if ('/' == uri.charAt(0)) { - if ('/' == uri.charAt(1)) { - uri = loc.protocol + uri; - } else { - uri = loc.hostname + uri; - } - } - - if (!/^(https?|wss?):\/\//.test(uri)) { - debug('protocol-less url %s', uri); - if ('undefined' != typeof loc) { - uri = loc.protocol + '//' + uri; - } else { - uri = 'https://' + uri; - } - } - - // parse - debug('parse %s', uri); - obj = parseuri(uri); - } - - // make sure we treat `localhost:80` and `localhost` equally - if (!obj.port) { - if (/^(http|ws)$/.test(obj.protocol)) { - obj.port = '80'; - } - else if (/^(http|ws)s$/.test(obj.protocol)) { - obj.port = '443'; - } - } - - obj.path = obj.path || '/'; - - // define unique id - obj.id = obj.protocol + '://' + obj.host + ':' + obj.port; - // define href - obj.href = obj.protocol + '://' + obj.host + (loc && loc.port == obj.port ? '' : (':' + obj.port)); - - return obj; - } - - }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"debug":10,"parseuri":44}],7:[function(_dereq_,module,exports){ - - /** - * Expose `Backoff`. - */ - - module.exports = Backoff; - - /** - * Initialize backoff timer with `opts`. - * - * - `min` initial timeout in milliseconds [100] - * - `max` max timeout [10000] - * - `jitter` [0] - * - `factor` [2] - * - * @param {Object} opts - * @api public - */ - - function Backoff(opts) { - opts = opts || {}; - this.ms = opts.min || 100; - this.max = opts.max || 10000; - this.factor = opts.factor || 2; - this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0; - this.attempts = 0; - } - - /** - * Return the backoff duration. - * - * @return {Number} - * @api public - */ - - Backoff.prototype.duration = function(){ - var ms = this.ms * Math.pow(this.factor, this.attempts++); - if (this.jitter) { - var rand = Math.random(); - var deviation = Math.floor(rand * this.jitter * ms); - ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation; - } - return Math.min(ms, this.max) | 0; - }; - - /** - * Reset the number of attempts. - * - * @api public - */ - - Backoff.prototype.reset = function(){ - this.attempts = 0; - }; - - /** - * Set the minimum duration - * - * @api public - */ - - Backoff.prototype.setMin = function(min){ - this.ms = min; - }; - - /** - * Set the maximum duration - * - * @api public - */ - - Backoff.prototype.setMax = function(max){ - this.max = max; - }; - - /** - * Set the jitter - * - * @api public - */ - - Backoff.prototype.setJitter = function(jitter){ - this.jitter = jitter; - }; - - -},{}],8:[function(_dereq_,module,exports){ - /** - * Slice reference. - */ - - var slice = [].slice; - - /** - * Bind `obj` to `fn`. - * - * @param {Object} obj - * @param {Function|String} fn or string - * @return {Function} - * @api public - */ - - module.exports = function(obj, fn){ - if ('string' == typeof fn) fn = obj[fn]; - if ('function' != typeof fn) throw new Error('bind() requires a function'); - var args = slice.call(arguments, 2); - return function(){ - return fn.apply(obj, args.concat(slice.call(arguments))); - } - }; - -},{}],9:[function(_dereq_,module,exports){ - - /** - * Expose `Emitter`. - */ - - module.exports = Emitter; - - /** - * Initialize a new `Emitter`. - * - * @api public - */ - - function Emitter(obj) { - if (obj) return mixin(obj); - }; - - /** - * Mixin the emitter properties. - * - * @param {Object} obj - * @return {Object} - * @api private - */ - - function mixin(obj) { - for (var key in Emitter.prototype) { - obj[key] = Emitter.prototype[key]; - } - return obj; - } - - /** - * Listen on the given `event` with `fn`. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - - Emitter.prototype.on = - Emitter.prototype.addEventListener = function(event, fn){ - this._callbacks = this._callbacks || {}; - (this._callbacks[event] = this._callbacks[event] || []) - .push(fn); - return this; - }; - - /** - * Adds an `event` listener that will be invoked a single - * time then automatically removed. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - - Emitter.prototype.once = function(event, fn){ - var self = this; - this._callbacks = this._callbacks || {}; - - function on() { - self.off(event, on); - fn.apply(this, arguments); - } - - on.fn = fn; - this.on(event, on); - return this; - }; - - /** - * Remove the given callback for `event` or all - * registered callbacks. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - - Emitter.prototype.off = - Emitter.prototype.removeListener = - Emitter.prototype.removeAllListeners = - Emitter.prototype.removeEventListener = function(event, fn){ - this._callbacks = this._callbacks || {}; - - // all - if (0 == arguments.length) { - this._callbacks = {}; - return this; - } - - // specific event - var callbacks = this._callbacks[event]; - if (!callbacks) return this; - - // remove all handlers - if (1 == arguments.length) { - delete this._callbacks[event]; - return this; - } - - // remove specific handler - var cb; - for (var i = 0; i < callbacks.length; i++) { - cb = callbacks[i]; - if (cb === fn || cb.fn === fn) { - callbacks.splice(i, 1); - break; - } - } - return this; - }; - - /** - * Emit `event` with the given args. - * - * @param {String} event - * @param {Mixed} ... - * @return {Emitter} - */ - - Emitter.prototype.emit = function(event){ - this._callbacks = this._callbacks || {}; - var args = [].slice.call(arguments, 1) - , callbacks = this._callbacks[event]; - - if (callbacks) { - callbacks = callbacks.slice(0); - for (var i = 0, len = callbacks.length; i < len; ++i) { - callbacks[i].apply(this, args); - } - } - - return this; - }; - - /** - * Return array of callbacks for `event`. - * - * @param {String} event - * @return {Array} - * @api public - */ - - Emitter.prototype.listeners = function(event){ - this._callbacks = this._callbacks || {}; - return this._callbacks[event] || []; - }; - - /** - * Check if this emitter has `event` handlers. - * - * @param {String} event - * @return {Boolean} - * @api public - */ - - Emitter.prototype.hasListeners = function(event){ - return !! this.listeners(event).length; - }; - -},{}],10:[function(_dereq_,module,exports){ - - /** - * Expose `debug()` as the module. - */ - - module.exports = debug; - - /** - * Create a debugger with the given `name`. - * - * @param {String} name - * @return {Type} - * @api public - */ - - function debug(name) { - if (!debug.enabled(name)) return function(){}; - - return function(fmt){ - fmt = coerce(fmt); - - var curr = new Date; - var ms = curr - (debug[name] || curr); - debug[name] = curr; - - fmt = name - + ' ' - + fmt - + ' +' + debug.humanize(ms); - - // This hackery is required for IE8 - // where `console.log` doesn't have 'apply' - window.console - && console.log - && Function.prototype.apply.call(console.log, console, arguments); - } - } - - /** - * The currently active debug mode names. - */ - - debug.names = []; - debug.skips = []; - - /** - * Enables a debug mode by name. This can include modes - * separated by a colon and wildcards. - * - * @param {String} name - * @api public - */ - - debug.enable = function(name) { - try { - localStorage.debug = name; - } catch(e){} - - var split = (name || '').split(/[\s,]+/) - , len = split.length; - - for (var i = 0; i < len; i++) { - name = split[i].replace('*', '.*?'); - if (name[0] === '-') { - debug.skips.push(new RegExp('^' + name.substr(1) + '$')); - } - else { - debug.names.push(new RegExp('^' + name + '$')); - } - } - }; - - /** - * Disable debug output. - * - * @api public - */ - - debug.disable = function(){ - debug.enable(''); - }; - - /** - * Humanize the given `ms`. - * - * @param {Number} m - * @return {String} - * @api private - */ - - debug.humanize = function(ms) { - var sec = 1000 - , min = 60 * 1000 - , hour = 60 * min; - - if (ms >= hour) return (ms / hour).toFixed(1) + 'h'; - if (ms >= min) return (ms / min).toFixed(1) + 'm'; - if (ms >= sec) return (ms / sec | 0) + 's'; - return ms + 'ms'; - }; - - /** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public - */ - - debug.enabled = function(name) { - for (var i = 0, len = debug.skips.length; i < len; i++) { - if (debug.skips[i].test(name)) { - return false; - } - } - for (var i = 0, len = debug.names.length; i < len; i++) { - if (debug.names[i].test(name)) { - return true; - } - } - return false; - }; - - /** - * Coerce `val`. - */ - - function coerce(val) { - if (val instanceof Error) return val.stack || val.message; - return val; - } - -// persist - - try { - if (window.localStorage) debug.enable(localStorage.debug); - } catch(e){} - -},{}],11:[function(_dereq_,module,exports){ - - module.exports = _dereq_('./lib/'); - -},{"./lib/":12}],12:[function(_dereq_,module,exports){ - - module.exports = _dereq_('./socket'); - - /** - * Exports parser - * - * @api public - * - */ - module.exports.parser = _dereq_('engine.io-parser'); - -},{"./socket":13,"engine.io-parser":25}],13:[function(_dereq_,module,exports){ - (function (global){ - /** - * Module dependencies. - */ - - var transports = _dereq_('./transports'); - var Emitter = _dereq_('component-emitter'); - var debug = _dereq_('debug')('engine.io-client:socket'); - var index = _dereq_('indexof'); - var parser = _dereq_('engine.io-parser'); - var parseuri = _dereq_('parseuri'); - var parsejson = _dereq_('parsejson'); - var parseqs = _dereq_('parseqs'); - - /** - * Module exports. - */ - - module.exports = Socket; - - /** - * Noop function. - * - * @api private - */ - - function noop(){} - - /** - * Socket constructor. - * - * @param {String|Object} uri or options - * @param {Object} options - * @api public - */ - - function Socket(uri, opts){ - if (!(this instanceof Socket)) return new Socket(uri, opts); - - opts = opts || {}; - - if (uri && 'object' == typeof uri) { - opts = uri; - uri = null; - } - - if (uri) { - uri = parseuri(uri); - opts.host = uri.host; - opts.secure = uri.protocol == 'https' || uri.protocol == 'wss'; - opts.port = uri.port; - if (uri.query) opts.query = uri.query; - } - - this.secure = null != opts.secure ? opts.secure : - (global.location && 'https:' == location.protocol); - - if (opts.host) { - var pieces = opts.host.split(':'); - opts.hostname = pieces.shift(); - if (pieces.length) { - opts.port = pieces.pop(); - } else if (!opts.port) { - // if no port is specified manually, use the protocol default - opts.port = this.secure ? '443' : '80'; - } - } - - this.agent = opts.agent || false; - this.hostname = opts.hostname || - (global.location ? location.hostname : 'localhost'); - this.port = opts.port || (global.location && location.port ? - location.port : - (this.secure ? 443 : 80)); - this.query = opts.query || {}; - if ('string' == typeof this.query) this.query = parseqs.decode(this.query); - this.upgrade = false !== opts.upgrade; - this.path = (opts.path || '/engine.io').replace(/\/$/, '') + '/'; - this.forceJSONP = !!opts.forceJSONP; - this.jsonp = false !== opts.jsonp; - this.forceBase64 = !!opts.forceBase64; - this.enablesXDR = !!opts.enablesXDR; - this.timestampParam = opts.timestampParam || 't'; - this.timestampRequests = opts.timestampRequests; - this.transports = opts.transports || ['polling', 'websocket']; - this.readyState = ''; - this.writeBuffer = []; - this.callbackBuffer = []; - this.policyPort = opts.policyPort || 843; - this.rememberUpgrade = opts.rememberUpgrade || false; - this.binaryType = null; - this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades; - - // SSL options for Node.js client - this.pfx = opts.pfx || null; - this.key = opts.key || null; - this.passphrase = opts.passphrase || null; - this.cert = opts.cert || null; - this.ca = opts.ca || null; - this.ciphers = opts.ciphers || null; - this.rejectUnauthorized = opts.rejectUnauthorized || null; - - this.open(); - } - - Socket.priorWebsocketSuccess = false; - - /** - * Mix in `Emitter`. - */ - - Emitter(Socket.prototype); - - /** - * Protocol version. - * - * @api public - */ - - Socket.protocol = parser.protocol; // this is an int - - /** - * Expose deps for legacy compatibility - * and standalone browser access. - */ - - Socket.Socket = Socket; - Socket.Transport = _dereq_('./transport'); - Socket.transports = _dereq_('./transports'); - Socket.parser = _dereq_('engine.io-parser'); - - /** - * Creates transport of the given type. - * - * @param {String} transport name - * @return {Transport} - * @api private - */ - - Socket.prototype.createTransport = function (name) { - debug('creating transport "%s"', name); - var query = clone(this.query); - - // append engine.io protocol identifier - query.EIO = parser.protocol; - - // transport name - query.transport = name; - - // session id if we already have one - if (this.id) query.sid = this.id; - - var transport = new transports[name]({ - agent: this.agent, - hostname: this.hostname, - port: this.port, - secure: this.secure, - path: this.path, - query: query, - forceJSONP: this.forceJSONP, - jsonp: this.jsonp, - forceBase64: this.forceBase64, - enablesXDR: this.enablesXDR, - timestampRequests: this.timestampRequests, - timestampParam: this.timestampParam, - policyPort: this.policyPort, - socket: this, - pfx: this.pfx, - key: this.key, - passphrase: this.passphrase, - cert: this.cert, - ca: this.ca, - ciphers: this.ciphers, - rejectUnauthorized: this.rejectUnauthorized - }); - - return transport; - }; - - function clone (obj) { - var o = {}; - for (var i in obj) { - if (obj.hasOwnProperty(i)) { - o[i] = obj[i]; - } - } - return o; - } - - /** - * Initializes transport to use and starts probe. - * - * @api private - */ - Socket.prototype.open = function () { - var transport; - if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') != -1) { - transport = 'websocket'; - } else if (0 == this.transports.length) { - // Emit error on next tick so it can be listened to - var self = this; - setTimeout(function() { - self.emit('error', 'No transports available'); - }, 0); - return; - } else { - transport = this.transports[0]; - } - this.readyState = 'opening'; - - // Retry with the next transport if the transport is disabled (jsonp: false) - var transport; - try { - transport = this.createTransport(transport); - } catch (e) { - this.transports.shift(); - this.open(); - return; - } - - transport.open(); - this.setTransport(transport); - }; - - /** - * Sets the current transport. Disables the existing one (if any). - * - * @api private - */ - - Socket.prototype.setTransport = function(transport){ - debug('setting transport %s', transport.name); - var self = this; - - if (this.transport) { - debug('clearing existing transport %s', this.transport.name); - this.transport.removeAllListeners(); - } - - // set up transport - this.transport = transport; - - // set up transport listeners - transport - .on('drain', function(){ - self.onDrain(); - }) - .on('packet', function(packet){ - self.onPacket(packet); - }) - .on('error', function(e){ - self.onError(e); - }) - .on('close', function(){ - self.onClose('transport close'); - }); - }; - - /** - * Probes a transport. - * - * @param {String} transport name - * @api private - */ - - Socket.prototype.probe = function (name) { - debug('probing transport "%s"', name); - var transport = this.createTransport(name, { probe: 1 }) - , failed = false - , self = this; - - Socket.priorWebsocketSuccess = false; - - function onTransportOpen(){ - if (self.onlyBinaryUpgrades) { - var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary; - failed = failed || upgradeLosesBinary; - } - if (failed) return; - - debug('probe transport "%s" opened', name); - transport.send([{ type: 'ping', data: 'probe' }]); - transport.once('packet', function (msg) { - if (failed) return; - if ('pong' == msg.type && 'probe' == msg.data) { - debug('probe transport "%s" pong', name); - self.upgrading = true; - self.emit('upgrading', transport); - if (!transport) return; - Socket.priorWebsocketSuccess = 'websocket' == transport.name; - - debug('pausing current transport "%s"', self.transport.name); - self.transport.pause(function () { - if (failed) return; - if ('closed' == self.readyState) return; - debug('changing transport and sending upgrade packet'); - - cleanup(); - - self.setTransport(transport); - transport.send([{ type: 'upgrade' }]); - self.emit('upgrade', transport); - transport = null; - self.upgrading = false; - self.flush(); - }); - } else { - debug('probe transport "%s" failed', name); - var err = new Error('probe error'); - err.transport = transport.name; - self.emit('upgradeError', err); - } - }); - } - - function freezeTransport() { - if (failed) return; - - // Any callback called by transport should be ignored since now - failed = true; - - cleanup(); - - transport.close(); - transport = null; - } - - //Handle any error that happens while probing - function onerror(err) { - var error = new Error('probe error: ' + err); - error.transport = transport.name; - - freezeTransport(); - - debug('probe transport "%s" failed because of error: %s', name, err); - - self.emit('upgradeError', error); - } - - function onTransportClose(){ - onerror("transport closed"); - } - - //When the socket is closed while we're probing - function onclose(){ - onerror("socket closed"); - } - - //When the socket is upgraded while we're probing - function onupgrade(to){ - if (transport && to.name != transport.name) { - debug('"%s" works - aborting "%s"', to.name, transport.name); - freezeTransport(); - } - } - - //Remove all listeners on the transport and on self - function cleanup(){ - transport.removeListener('open', onTransportOpen); - transport.removeListener('error', onerror); - transport.removeListener('close', onTransportClose); - self.removeListener('close', onclose); - self.removeListener('upgrading', onupgrade); - } - - transport.once('open', onTransportOpen); - transport.once('error', onerror); - transport.once('close', onTransportClose); - - this.once('close', onclose); - this.once('upgrading', onupgrade); - - transport.open(); - - }; - - /** - * Called when connection is deemed open. - * - * @api public - */ - - Socket.prototype.onOpen = function () { - debug('socket open'); - this.readyState = 'open'; - Socket.priorWebsocketSuccess = 'websocket' == this.transport.name; - this.emit('open'); - this.flush(); - - // we check for `readyState` in case an `open` - // listener already closed the socket - if ('open' == this.readyState && this.upgrade && this.transport.pause) { - debug('starting upgrade probes'); - for (var i = 0, l = this.upgrades.length; i < l; i++) { - this.probe(this.upgrades[i]); - } - } - }; - - /** - * Handles a packet. - * - * @api private - */ - - Socket.prototype.onPacket = function (packet) { - if ('opening' == this.readyState || 'open' == this.readyState) { - debug('socket receive: type "%s", data "%s"', packet.type, packet.data); - - this.emit('packet', packet); - - // Socket is live - any packet counts - this.emit('heartbeat'); - - switch (packet.type) { - case 'open': - this.onHandshake(parsejson(packet.data)); - break; - - case 'pong': - this.setPing(); - break; - - case 'error': - var err = new Error('server error'); - err.code = packet.data; - this.emit('error', err); - break; - - case 'message': - this.emit('data', packet.data); - this.emit('message', packet.data); - break; - } - } else { - debug('packet received with socket readyState "%s"', this.readyState); - } - }; - - /** - * Called upon handshake completion. - * - * @param {Object} handshake obj - * @api private - */ - - Socket.prototype.onHandshake = function (data) { - this.emit('handshake', data); - this.id = data.sid; - this.transport.query.sid = data.sid; - this.upgrades = this.filterUpgrades(data.upgrades); - this.pingInterval = data.pingInterval; - this.pingTimeout = data.pingTimeout; - this.onOpen(); - // In case open handler closes socket - if ('closed' == this.readyState) return; - this.setPing(); - - // Prolong liveness of socket on heartbeat - this.removeListener('heartbeat', this.onHeartbeat); - this.on('heartbeat', this.onHeartbeat); - }; - - /** - * Resets ping timeout. - * - * @api private - */ - - Socket.prototype.onHeartbeat = function (timeout) { - clearTimeout(this.pingTimeoutTimer); - var self = this; - self.pingTimeoutTimer = setTimeout(function () { - if ('closed' == self.readyState) return; - self.onClose('ping timeout'); - }, timeout || (self.pingInterval + self.pingTimeout)); - }; - - /** - * Pings server every `this.pingInterval` and expects response - * within `this.pingTimeout` or closes connection. - * - * @api private - */ - - Socket.prototype.setPing = function () { - var self = this; - clearTimeout(self.pingIntervalTimer); - self.pingIntervalTimer = setTimeout(function () { - debug('writing ping packet - expecting pong within %sms', self.pingTimeout); - self.ping(); - self.onHeartbeat(self.pingTimeout); - }, self.pingInterval); - }; - - /** - * Sends a ping packet. - * - * @api public - */ - - Socket.prototype.ping = function () { - this.sendPacket('ping'); - }; - - /** - * Called on `drain` event - * - * @api private - */ - - Socket.prototype.onDrain = function() { - for (var i = 0; i < this.prevBufferLen; i++) { - if (this.callbackBuffer[i]) { - this.callbackBuffer[i](); - } - } - - this.writeBuffer.splice(0, this.prevBufferLen); - this.callbackBuffer.splice(0, this.prevBufferLen); - - // setting prevBufferLen = 0 is very important - // for example, when upgrading, upgrade packet is sent over, - // and a nonzero prevBufferLen could cause problems on `drain` - this.prevBufferLen = 0; - - if (this.writeBuffer.length == 0) { - this.emit('drain'); - } else { - this.flush(); - } - }; - - /** - * Flush write buffers. - * - * @api private - */ - - Socket.prototype.flush = function () { - if ('closed' != this.readyState && this.transport.writable && - !this.upgrading && this.writeBuffer.length) { - debug('flushing %d packets in socket', this.writeBuffer.length); - this.transport.send(this.writeBuffer); - // keep track of current length of writeBuffer - // splice writeBuffer and callbackBuffer on `drain` - this.prevBufferLen = this.writeBuffer.length; - this.emit('flush'); - } - }; - - /** - * Sends a message. - * - * @param {String} message. - * @param {Function} callback function. - * @return {Socket} for chaining. - * @api public - */ - - Socket.prototype.write = - Socket.prototype.send = function (msg, fn) { - this.sendPacket('message', msg, fn); - return this; - }; - - /** - * Sends a packet. - * - * @param {String} packet type. - * @param {String} data. - * @param {Function} callback function. - * @api private - */ - - Socket.prototype.sendPacket = function (type, data, fn) { - if ('closing' == this.readyState || 'closed' == this.readyState) { - return; - } - - var packet = { type: type, data: data }; - this.emit('packetCreate', packet); - this.writeBuffer.push(packet); - this.callbackBuffer.push(fn); - this.flush(); - }; - - /** - * Closes the connection. - * - * @api private - */ - - Socket.prototype.close = function () { - if ('opening' == this.readyState || 'open' == this.readyState) { - this.readyState = 'closing'; - - var self = this; - - function close() { - self.onClose('forced close'); - debug('socket closing - telling transport to close'); - self.transport.close(); - } - - function cleanupAndClose() { - self.removeListener('upgrade', cleanupAndClose); - self.removeListener('upgradeError', cleanupAndClose); - close(); - } - - function waitForUpgrade() { - // wait for upgrade to finish since we can't send packets while pausing a transport - self.once('upgrade', cleanupAndClose); - self.once('upgradeError', cleanupAndClose); - } - - if (this.writeBuffer.length) { - this.once('drain', function() { - if (this.upgrading) { - waitForUpgrade(); - } else { - close(); - } - }); - } else if (this.upgrading) { - waitForUpgrade(); - } else { - close(); - } - } - - return this; - }; - - /** - * Called upon transport error - * - * @api private - */ - - Socket.prototype.onError = function (err) { - debug('socket error %j', err); - Socket.priorWebsocketSuccess = false; - this.emit('error', err); - this.onClose('transport error', err); - }; - - /** - * Called upon transport close. - * - * @api private - */ - - Socket.prototype.onClose = function (reason, desc) { - if ('opening' == this.readyState || 'open' == this.readyState || 'closing' == this.readyState) { - debug('socket close with reason: "%s"', reason); - var self = this; - - // clear timers - clearTimeout(this.pingIntervalTimer); - clearTimeout(this.pingTimeoutTimer); - - // clean buffers in next tick, so developers can still - // grab the buffers on `close` event - setTimeout(function() { - self.writeBuffer = []; - self.callbackBuffer = []; - self.prevBufferLen = 0; - }, 0); - - // stop event from firing again for transport - this.transport.removeAllListeners('close'); - - // ensure transport won't stay open - this.transport.close(); - - // ignore further transport communication - this.transport.removeAllListeners(); - - // set ready state - this.readyState = 'closed'; - - // clear session id - this.id = null; - - // emit close event - this.emit('close', reason, desc); - } - }; - - /** - * Filters upgrades, returning only those matching client transports. - * - * @param {Array} server upgrades - * @api private - * - */ - - Socket.prototype.filterUpgrades = function (upgrades) { - var filteredUpgrades = []; - for (var i = 0, j = upgrades.length; i