1 /**************************************************************************** 2 Copyright (c) 2011-2012 cocos2d-x.org 3 Copyright (c) 2013-2014 Chukong Technologies Inc. 4 5 http://www.cocos2d-x.org 6 7 Permission is hereby granted, free of charge, to any person obtaining a copy 8 of this software and associated documentation files (the "Software"), to deal 9 in the Software without restriction, including without limitation the rights 10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 copies of the Software, and to permit persons to whom the Software is 12 furnished to do so, subject to the following conditions: 13 14 The above copyright notice and this permission notice shall be included in 15 all copies or substantial portions of the Software. 16 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 THE SOFTWARE. 24 ****************************************************************************/ 25 26 /** 27 * ccs.Bone uses ccs.Skin to displays on screen. 28 * @class 29 * @extends ccs.Sprite 30 * 31 * @property {Object} skinData - The data of the skin 32 * @property {ccs.Bone} bone - The bone of the skin 33 * @property {String} displayName - <@readonly> The displayed name of skin 34 * 35 */ 36 ccs.Skin = ccs.Sprite.extend(/** @lends ccs.Skin# */{ 37 _skinData: null, 38 bone: null, 39 _skinTransform: null, 40 _displayName: "", 41 _armature: null, 42 _className: "Skin", 43 44 ctor: function () { 45 cc.Sprite.prototype.ctor.call(this); 46 this._skinData = null; 47 this.bone = null; 48 this._displayName = ""; 49 this._skinTransform = cc.affineTransformIdentity(); 50 this._armature = null; 51 }, 52 53 initWithSpriteFrameName: function (spriteFrameName) { 54 if(spriteFrameName == "") 55 return false; 56 var pFrame = cc.spriteFrameCache.getSpriteFrame(spriteFrameName); 57 var ret = true; 58 if(pFrame) 59 this.initWithSpriteFrame(pFrame); 60 else{ 61 cc.log("Can't find CCSpriteFrame with %s. Please check your .plist file", spriteFrameName); 62 ret = false; 63 } 64 this._displayName = spriteFrameName; 65 return ret; 66 }, 67 68 initWithFile: function (fileName) { 69 var ret = cc.Sprite.prototype.initWithFile.call(this, fileName); 70 this._displayName = fileName; 71 return ret; 72 }, 73 74 setSkinData: function (skinData) { 75 this._skinData = skinData; 76 this.setScaleX(skinData.scaleX); 77 this.setScaleY(skinData.scaleY); 78 this.setRotationX(cc.radiansToDegrees(skinData.skewX)); 79 this.setRotationY(cc.radiansToDegrees(-skinData.skewY)); 80 this.setPosition(skinData.x, skinData.y); 81 82 var localTransform = this.getNodeToParentTransform ? this.getNodeToParentTransform() : this.nodeToParentTransform(); 83 var skinTransform = this._skinTransform; 84 skinTransform.a = localTransform.a; 85 skinTransform.b = localTransform.b; 86 skinTransform.c = localTransform.c; 87 skinTransform.d = localTransform.d; 88 skinTransform.tx = localTransform.tx; 89 skinTransform.ty = localTransform.ty; 90 this.updateArmatureTransform(); 91 }, 92 93 getSkinData: function () { 94 return this._skinData; 95 }, 96 97 updateArmatureTransform: function () { 98 this._transform = cc.affineTransformConcat( 99 this._skinTransform, 100 this.bone.getNodeToArmatureTransform() 101 ); 102 }, 103 104 _updateTransformForWebGL: function(){ 105 var locQuad = this._quad; 106 // If it is not visible, or one of its ancestors is not visible, then do nothing: 107 if( !this._visible) 108 locQuad.br.vertices = locQuad.tl.vertices = locQuad.tr.vertices = locQuad.bl.vertices = {x: 0, y:0, z:0}; 109 else { 110 // 111 // calculate the Quad based on the Affine Matrix 112 // 113 var transform = this.getNodeToParentTransform ? this.getNodeToParentTransform() : this.nodeToParentTransform(); 114 var size = this._rect; 115 116 var x1 = this._offsetPosition.x, y1 = this._offsetPosition.y; 117 118 var x2 = x1 + size.width, y2 = y1 + size.height; 119 var x = transform.tx, y = transform.ty; 120 121 var cr = transform.a, sr = transform.b; 122 var cr2 = transform.d, sr2 = -transform.c; 123 var ax = x1 * cr - y1 * sr2 + x; 124 var ay = x1 * sr + y1 * cr2 + y; 125 126 var bx = x2 * cr - y1 * sr2 + x; 127 var by = x2 * sr + y1 * cr2 + y; 128 129 var cx = x2 * cr - y2 * sr2 + x; 130 var cy = x2 * sr + y2 * cr2 + y; 131 132 var dx = x1 * cr - y2 * sr2 + x; 133 var dy = x1 * sr + y2 * cr2 + y; 134 135 var locVertexZ = this._vertexZ; 136 if(!cc.SPRITEBATCHNODE_RENDER_SUBPIXEL) { 137 ax = 0 | ax; 138 ay = 0 | ay; 139 bx = 0 | bx; 140 by = 0 | by; 141 cx = 0 | cx; 142 cy = 0 | cy; 143 dx = 0 | dx; 144 dy = 0 | dy; 145 } 146 this.SET_VERTEX3F(locQuad.bl.vertices,ax, ay,locVertexZ); 147 this.SET_VERTEX3F(locQuad.br.vertices,bx, by,locVertexZ); 148 this.SET_VERTEX3F(locQuad.tl.vertices,dx, dy,locVertexZ); 149 this.SET_VERTEX3F(locQuad.tr.vertices,cx, cy,locVertexZ); 150 } 151 152 // MARMALADE CHANGE: ADDED CHECK FOR nullptr, TO PERMIT SPRITES WITH NO BATCH NODE / TEXTURE ATLAS 153 if (this._textureAtlas) 154 this._textureAtlas.updateQuad(locQuad, this._textureAtlas.getTotalQuads()); 155 this._quadDirty = true; 156 }, 157 158 SET_VERTEX3F: function(_v_, _x_, _y_, _z_){ 159 (_v_).x = (_x_); 160 (_v_).y = (_y_); 161 (_v_).z = (_z_); 162 }, 163 164 RENDER_IN_SUBPIXEL: function(__ARGS__){ 165 if(!cc.SPRITEBATCHNODE_RENDER_SUBPIXEL) 166 return Math.ceil(__ARGS__); 167 else 168 return __ARGS__; 169 }, 170 171 getNodeToWorldTransform: function(){ 172 return cc.affineTransformConcat(this._transform,this.bone.getArmature().getNodeToWorldTransform()); 173 }, 174 175 getNodeToWorldTransformAR: function(){ 176 var displayTransform = this._transform; 177 this._anchorPointInPoints = cc.pointApplyAffineTransform(this._anchorPointInPoints, displayTransform); 178 displayTransform.tx = this._anchorPointInPoints.x; 179 displayTransform.ty = this._anchorPointInPoints.y; 180 return cc.affineTransformConcat( displayTransform,this.bone.getArmature().nodeToWorldTransform()); 181 }, 182 183 setBone: function (bone) { 184 this.bone = bone; 185 var armature = this.bone.getArmature(); 186 if(armature) 187 this._armature = armature; 188 }, 189 190 getBone: function () { 191 return this.bone; 192 }, 193 194 /** 195 * display name getter 196 * @returns {String} 197 */ 198 getDisplayName: function () { 199 return this._displayName; 200 } 201 }); 202 if (cc._renderType == cc._RENDER_TYPE_WEBGL) { 203 ccs.Skin.prototype.updateTransform = ccs.Skin.prototype._updateTransformForWebGL; 204 }else{ 205 //ccs.Skin.prototype.getNodeToParentTransform = cc.Node.prototype._getNodeToParentTransformForWebGL; 206 } 207 //ccs.Skin.prototype.nodeToParentTransform = cc.Node.prototype._getNodeToParentTransformForWebGL; 208 209 210 var _p = ccs.Skin.prototype; 211 212 // Extended properties 213 /** @expose */ 214 _p.skinData; 215 cc.defineGetterSetter(_p, "skinData", _p.getSkinData, _p.setSkinData); 216 /** @expose */ 217 _p.displayName; 218 cc.defineGetterSetter(_p, "displayName", _p.getDisplayName); 219 220 _p = null; 221 222 /** 223 * allocates and initializes a skin. 224 * @param {String} [fileName] fileName or sprite frame name 225 * @param {cc.Rect} [rect] 226 * @returns {ccs.Skin} 227 * @example 228 * // example 229 * var skin = ccs.Skin.create("res/test.png",cc.rect(0,0,50,50)); 230 * var skin = ccs.Skin.create("#test.png"); //=> ccs.Skin.createWithSpriteFrameName("test.png"); 231 */ 232 ccs.Skin.create = function (fileName, rect) { 233 var argnum = arguments.length; 234 var skin = new ccs.Skin(); 235 if (argnum === 0 || fileName == null || fileName == "") { 236 if (skin.init()) 237 return skin; 238 } else { 239 if(fileName[0] == "#"){ 240 if (skin && skin.initWithSpriteFrameName(fileName)) 241 return skin; 242 }else{ 243 if (skin && skin.initWithFile(fileName, rect)) 244 return skin; 245 } 246 } 247 return null; 248 }; 249 250 /** 251 * allocates and initializes a skin. 252 * @param {String} spriteFrameName 253 * @returns {ccs.Skin} 254 * @example 255 * // example 256 * var skin = ccs.Skin.createWithSpriteFrameName("test.png"); 257 */ 258 ccs.Skin.createWithSpriteFrameName = function (spriteFrameName) { 259 var skin = new ccs.Skin(); 260 if (skin && skin.initWithSpriteFrameName(spriteFrameName)) 261 return skin; 262 return null; 263 }; 264