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 /** 45 * Construction of ccs.Skin. 46 */ 47 ctor: function () { 48 cc.Sprite.prototype.ctor.call(this); 49 this._skinData = null; 50 this.bone = null; 51 this._displayName = ""; 52 this._skinTransform = cc.affineTransformIdentity(); 53 this._armature = null; 54 }, 55 56 /** 57 * Initializes with sprite frame name 58 * @param {String} spriteFrameName 59 * @returns {Boolean} 60 */ 61 initWithSpriteFrameName: function (spriteFrameName) { 62 if(spriteFrameName == "") 63 return false; 64 var pFrame = cc.spriteFrameCache.getSpriteFrame(spriteFrameName); 65 var ret = true; 66 if(pFrame) 67 this.initWithSpriteFrame(pFrame); 68 else{ 69 cc.log("Can't find CCSpriteFrame with %s. Please check your .plist file", spriteFrameName); 70 ret = false; 71 } 72 this._displayName = spriteFrameName; 73 return ret; 74 }, 75 76 /** 77 * Initializes with texture file name. 78 * @param {String} fileName 79 * @returns {Boolean} 80 */ 81 initWithFile: function (fileName) { 82 var ret = cc.Sprite.prototype.initWithFile.call(this, fileName); 83 this._displayName = fileName; 84 return ret; 85 }, 86 87 /** 88 * Sets skin data to ccs.Skin. 89 * @param {ccs.BaseData} skinData 90 */ 91 setSkinData: function (skinData) { 92 this._skinData = skinData; 93 this.setScaleX(skinData.scaleX); 94 this.setScaleY(skinData.scaleY); 95 this.setRotationX(cc.radiansToDegrees(skinData.skewX)); 96 this.setRotationY(cc.radiansToDegrees(-skinData.skewY)); 97 this.setPosition(skinData.x, skinData.y); 98 99 var localTransform = this.getNodeToParentTransform ? this.getNodeToParentTransform() : this.nodeToParentTransform(); 100 var skinTransform = this._skinTransform; 101 skinTransform.a = localTransform.a; 102 skinTransform.b = localTransform.b; 103 skinTransform.c = localTransform.c; 104 skinTransform.d = localTransform.d; 105 skinTransform.tx = localTransform.tx; 106 skinTransform.ty = localTransform.ty; 107 this.updateArmatureTransform(); 108 }, 109 110 /** 111 * Returns skin date of ccs.Skin. 112 * @returns {ccs.BaseData} 113 */ 114 getSkinData: function () { 115 return this._skinData; 116 }, 117 118 /** 119 * Updates armature skin's transform with skin transform and bone's transform. 120 */ 121 updateArmatureTransform: function () { 122 this._transform = cc.affineTransformConcat( 123 this._skinTransform, 124 this.bone.getNodeToArmatureTransform() 125 ); 126 }, 127 128 _updateTransformForWebGL: function(){ 129 var locQuad = this._quad; 130 // If it is not visible, or one of its ancestors is not visible, then do nothing: 131 if( !this._visible) 132 locQuad.br.vertices = locQuad.tl.vertices = locQuad.tr.vertices = locQuad.bl.vertices = {x: 0, y:0, z:0}; 133 else { 134 // 135 // calculate the Quad based on the Affine Matrix 136 // 137 var transform = this.getNodeToParentTransform ? this.getNodeToParentTransform() : this.nodeToParentTransform(); 138 var size = this._rect; 139 140 var x1 = this._offsetPosition.x, y1 = this._offsetPosition.y; 141 142 var x2 = x1 + size.width, y2 = y1 + size.height; 143 var x = transform.tx, y = transform.ty; 144 145 var cr = transform.a, sr = transform.b; 146 var cr2 = transform.d, sr2 = -transform.c; 147 var ax = x1 * cr - y1 * sr2 + x; 148 var ay = x1 * sr + y1 * cr2 + y; 149 150 var bx = x2 * cr - y1 * sr2 + x; 151 var by = x2 * sr + y1 * cr2 + y; 152 153 var cx = x2 * cr - y2 * sr2 + x; 154 var cy = x2 * sr + y2 * cr2 + y; 155 156 var dx = x1 * cr - y2 * sr2 + x; 157 var dy = x1 * sr + y2 * cr2 + y; 158 159 var locVertexZ = this._vertexZ; 160 if(!cc.SPRITEBATCHNODE_RENDER_SUBPIXEL) { 161 ax = 0 | ax; 162 ay = 0 | ay; 163 bx = 0 | bx; 164 by = 0 | by; 165 cx = 0 | cx; 166 cy = 0 | cy; 167 dx = 0 | dx; 168 dy = 0 | dy; 169 } 170 this.SET_VERTEX3F(locQuad.bl.vertices,ax, ay,locVertexZ); 171 this.SET_VERTEX3F(locQuad.br.vertices,bx, by,locVertexZ); 172 this.SET_VERTEX3F(locQuad.tl.vertices,dx, dy,locVertexZ); 173 this.SET_VERTEX3F(locQuad.tr.vertices,cx, cy,locVertexZ); 174 } 175 176 // MARMALADE CHANGE: ADDED CHECK FOR nullptr, TO PERMIT SPRITES WITH NO BATCH NODE / TEXTURE ATLAS 177 if (this._textureAtlas) 178 this._textureAtlas.updateQuad(locQuad, this._textureAtlas.getTotalQuads()); 179 this._quadDirty = true; 180 }, 181 182 SET_VERTEX3F: function(_v_, _x_, _y_, _z_){ 183 (_v_).x = (_x_); 184 (_v_).y = (_y_); 185 (_v_).z = (_z_); 186 }, 187 188 RENDER_IN_SUBPIXEL: function(__ARGS__){ 189 if(!cc.SPRITEBATCHNODE_RENDER_SUBPIXEL) 190 return Math.ceil(__ARGS__); 191 else 192 return __ARGS__; 193 }, 194 195 /** 196 * Returns skin's world transform. 197 * @returns {cc.AffineTransform} 198 */ 199 getNodeToWorldTransform: function(){ 200 return cc.affineTransformConcat(this._transform,this.bone.getArmature().getNodeToWorldTransform()); 201 }, 202 203 getNodeToWorldTransformAR: function(){ 204 var displayTransform = this._transform; 205 this._anchorPointInPoints = cc.pointApplyAffineTransform(this._anchorPointInPoints, displayTransform); 206 displayTransform.tx = this._anchorPointInPoints.x; 207 displayTransform.ty = this._anchorPointInPoints.y; 208 return cc.affineTransformConcat( displayTransform,this.bone.getArmature().nodeToWorldTransform()); 209 }, 210 211 /** 212 * Sets the bone reference to ccs.Skin. 213 * @param bone 214 */ 215 setBone: function (bone) { 216 this.bone = bone; 217 var armature = this.bone.getArmature(); 218 if(armature) 219 this._armature = armature; 220 }, 221 222 /** 223 * Returns the bone reference of ccs.Skin. 224 * @returns {null} 225 */ 226 getBone: function () { 227 return this.bone; 228 }, 229 230 /** 231 * display name getter 232 * @returns {String} 233 */ 234 getDisplayName: function () { 235 return this._displayName; 236 } 237 }); 238 if (cc._renderType == cc._RENDER_TYPE_WEBGL) { 239 ccs.Skin.prototype.updateTransform = ccs.Skin.prototype._updateTransformForWebGL; 240 }else{ 241 //ccs.Skin.prototype.getNodeToParentTransform = cc.Node.prototype._getNodeToParentTransformForWebGL; 242 } 243 //ccs.Skin.prototype.nodeToParentTransform = cc.Node.prototype._getNodeToParentTransformForWebGL; 244 245 246 var _p = ccs.Skin.prototype; 247 248 // Extended properties 249 /** @expose */ 250 _p.skinData; 251 cc.defineGetterSetter(_p, "skinData", _p.getSkinData, _p.setSkinData); 252 /** @expose */ 253 _p.displayName; 254 cc.defineGetterSetter(_p, "displayName", _p.getDisplayName); 255 256 _p = null; 257 258 /** 259 * allocates and initializes a skin. 260 * @param {String} [fileName] fileName or sprite frame name 261 * @param {cc.Rect} [rect] 262 * @returns {ccs.Skin} 263 * @example 264 * // example 265 * var skin = ccs.Skin.create("res/test.png",cc.rect(0,0,50,50)); 266 * var skin = ccs.Skin.create("#test.png"); //=> ccs.Skin.createWithSpriteFrameName("test.png"); 267 */ 268 ccs.Skin.create = function (fileName, rect) { 269 var argnum = arguments.length; 270 var skin = new ccs.Skin(); 271 if (argnum === 0 || fileName == null || fileName == "") { 272 if (skin.init()) 273 return skin; 274 } else { 275 if(fileName[0] == "#"){ 276 if (skin && skin.initWithSpriteFrameName(fileName)) 277 return skin; 278 }else{ 279 if (skin && skin.initWithFile(fileName, rect)) 280 return skin; 281 } 282 } 283 return null; 284 }; 285 286 /** 287 * allocates and initializes a skin. 288 * @param {String} spriteFrameName 289 * @returns {ccs.Skin} 290 * @example 291 * // example 292 * var skin = ccs.Skin.createWithSpriteFrameName("test.png"); 293 */ 294 ccs.Skin.createWithSpriteFrameName = function (spriteFrameName) { 295 var skin = new ccs.Skin(); 296 if (skin && skin.initWithSpriteFrameName(spriteFrameName)) 297 return skin; 298 return null; 299 }; 300