1 /**************************************************************************** 2 Copyright (c) 2008-2010 Ricardo Quesada 3 Copyright (c) 2011-2012 cocos2d-x.org 4 Copyright (c) 2013-2014 Chukong Technologies Inc. 5 6 http://www.cocos2d-x.org 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy 9 of this software and associated documentation files (the "Software"), to deal 10 in the Software without restriction, including without limitation the rights 11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 copies of the Software, and to permit persons to whom the Software is 13 furnished to do so, subject to the following conditions: 14 15 The above copyright notice and this permission notice shall be included in 16 all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 THE SOFTWARE. 25 ****************************************************************************/ 26 27 /** 28 * @constant 29 * @type Number 30 */ 31 cc.INVALID_INDEX = -1; 32 33 /** 34 * PI is the ratio of a circle's circumference to its diameter. 35 * @constant 36 * @type Number 37 */ 38 cc.PI = Math.PI; 39 40 /** 41 * @constant 42 * @type Number 43 */ 44 cc.FLT_MAX = parseFloat('3.402823466e+38F'); 45 46 /** 47 * @constant 48 * @type Number 49 */ 50 cc.FLT_MIN = parseFloat("1.175494351e-38F"); 51 52 /** 53 * @constant 54 * @type Number 55 */ 56 cc.RAD = cc.PI / 180; 57 58 /** 59 * @constant 60 * @type Number 61 */ 62 cc.DEG = 180 / cc.PI; 63 64 /** 65 * maximum unsigned int value 66 * @constant 67 * @type Number 68 */ 69 cc.UINT_MAX = 0xffffffff; 70 71 /** 72 * <p> 73 * simple macro that swaps 2 variables<br/> 74 * modified from c++ macro, you need to pass in the x and y variables names in string, <br/> 75 * and then a reference to the whole object as third variable 76 * </p> 77 * @param {String} x 78 * @param {String} y 79 * @param {Object} ref 80 * @function 81 * @deprecated since v3.0 82 */ 83 cc.swap = function (x, y, ref) { 84 if (cc.isObject(ref) && !cc.isUndefined(ref.x) && !cc.isUndefined(ref.y)) { 85 var tmp = ref[x]; 86 ref[x] = ref[y]; 87 ref[y] = tmp; 88 } else 89 cc.log(cc._LogInfos.swap); 90 }; 91 92 /** 93 * <p> 94 * Linear interpolation between 2 numbers, the ratio sets how much it is biased to each end 95 * </p> 96 * @param {Number} a number A 97 * @param {Number} b number B 98 * @param {Number} r ratio between 0 and 1 99 * @function 100 * @example 101 * cc.lerp(2,10,0.5)//returns 6<br/> 102 * cc.lerp(2,10,0.2)//returns 3.6 103 */ 104 cc.lerp = function (a, b, r) { 105 return a + (b - a) * r; 106 }; 107 108 /** 109 * get a random number from 0 to 0xffffff 110 * @function 111 * @returns {number} 112 */ 113 cc.rand = function () { 114 return Math.random() * 0xffffff; 115 }; 116 117 /** 118 * returns a random float between -1 and 1 119 * @return {Number} 120 * @function 121 */ 122 cc.randomMinus1To1 = function () { 123 return (Math.random() - 0.5) * 2; 124 }; 125 126 /** 127 * returns a random float between 0 and 1 128 * @return {Number} 129 * @function 130 */ 131 cc.random0To1 = Math.random; 132 133 /** 134 * converts degrees to radians 135 * @param {Number} angle 136 * @return {Number} 137 * @function 138 */ 139 cc.degreesToRadians = function (angle) { 140 return angle * cc.RAD; 141 }; 142 143 /** 144 * converts radians to degrees 145 * @param {Number} angle 146 * @return {Number} 147 * @function 148 */ 149 cc.radiansToDegrees = function (angle) { 150 return angle * cc.DEG; 151 }; 152 /** 153 * converts radians to degrees 154 * @param {Number} angle 155 * @return {Number} 156 * @function 157 */ 158 cc.radiansToDegress = function (angle) { 159 cc.log(cc._LogInfos.radiansToDegress); 160 return angle * cc.DEG; 161 }; 162 163 /** 164 * @constant 165 * @type Number 166 */ 167 cc.REPEAT_FOREVER = Number.MAX_VALUE - 1; 168 169 /** 170 * Helpful macro that setups the GL server state, the correct GL program and sets the Model View Projection matrix 171 * @param {cc.Node} node setup node 172 * @function 173 */ 174 cc.nodeDrawSetup = function (node) { 175 //cc.glEnable(node._glServerState); 176 if (node._shaderProgram) { 177 //cc._renderContext.useProgram(node._shaderProgram._programObj); 178 node._shaderProgram.use(); 179 node._shaderProgram.setUniformForModelViewAndProjectionMatrixWithMat4(); 180 } 181 }; 182 183 /** 184 * <p> 185 * GL states that are enabled:<br/> 186 * - GL_TEXTURE_2D<br/> 187 * - GL_VERTEX_ARRAY<br/> 188 * - GL_TEXTURE_COORD_ARRAY<br/> 189 * - GL_COLOR_ARRAY<br/> 190 * </p> 191 * @function 192 */ 193 cc.enableDefaultGLStates = function () { 194 //TODO OPENGL STUFF 195 /* 196 glEnableClientState(GL_VERTEX_ARRAY); 197 glEnableClientState(GL_COLOR_ARRAY); 198 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 199 glEnable(GL_TEXTURE_2D);*/ 200 }; 201 202 /** 203 * <p> 204 * Disable default GL states:<br/> 205 * - GL_TEXTURE_2D<br/> 206 * - GL_TEXTURE_COORD_ARRAY<br/> 207 * - GL_COLOR_ARRAY<br/> 208 * </p> 209 * @function 210 */ 211 cc.disableDefaultGLStates = function () { 212 //TODO OPENGL 213 /* 214 glDisable(GL_TEXTURE_2D); 215 glDisableClientState(GL_COLOR_ARRAY); 216 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 217 glDisableClientState(GL_VERTEX_ARRAY); 218 */ 219 }; 220 221 /** 222 * <p> 223 * Increments the GL Draws counts by one.<br/> 224 * The number of calls per frame are displayed on the screen when the CCDirector's stats are enabled.<br/> 225 * </p> 226 * @param {Number} addNumber 227 * @function 228 */ 229 cc.incrementGLDraws = function (addNumber) { 230 cc.g_NumberOfDraws += addNumber; 231 }; 232 233 /** 234 * @constant 235 * @type Number 236 */ 237 cc.FLT_EPSILON = 0.0000001192092896; 238 239 /** 240 * <p> 241 * On Mac it returns 1;<br/> 242 * On iPhone it returns 2 if RetinaDisplay is On. Otherwise it returns 1 243 * </p> 244 * @return {Number} 245 * @function 246 */ 247 cc.contentScaleFactor = cc.IS_RETINA_DISPLAY_SUPPORTED ? function () { 248 return cc.director.getContentScaleFactor(); 249 } : function () { 250 return 1; 251 }; 252 253 /** 254 * Converts a Point in points to pixels 255 * @param {cc.Point} points 256 * @return {cc.Point} 257 * @function 258 */ 259 cc.pointPointsToPixels = function (points) { 260 var scale = cc.contentScaleFactor(); 261 return cc.p(points.x * scale, points.y * scale); 262 }; 263 264 /** 265 * Converts a Point in pixels to points 266 * @param {cc.Rect} pixels 267 * @return {cc.Point} 268 * @function 269 */ 270 cc.pointPixelsToPoints = function (pixels) { 271 var scale = cc.contentScaleFactor(); 272 return cc.p(pixels.x / scale, pixels.y / scale); 273 }; 274 275 cc._pointPixelsToPointsOut = function(pixels, outPoint){ 276 var scale = cc.contentScaleFactor(); 277 outPoint.x = pixels.x / scale; 278 outPoint.y = pixels.y / scale; 279 }; 280 281 /** 282 * Converts a Size in points to pixels 283 * @param {cc.Size} sizeInPoints 284 * @return {cc.Size} 285 * @function 286 */ 287 cc.sizePointsToPixels = function (sizeInPoints) { 288 var scale = cc.contentScaleFactor(); 289 return cc.size(sizeInPoints.width * scale, sizeInPoints.height * scale); 290 }; 291 292 /** 293 * Converts a size in pixels to points 294 * @param {cc.Size} sizeInPixels 295 * @return {cc.Size} 296 * @function 297 */ 298 cc.sizePixelsToPoints = function (sizeInPixels) { 299 var scale = cc.contentScaleFactor(); 300 return cc.size(sizeInPixels.width / scale, sizeInPixels.height / scale); 301 }; 302 303 cc._sizePixelsToPointsOut = function (sizeInPixels, outSize) { 304 var scale = cc.contentScaleFactor(); 305 outSize.width = sizeInPixels.width / scale; 306 outSize.height = sizeInPixels.height / scale; 307 }; 308 309 /** 310 * Converts a rect in pixels to points 311 * @param {cc.Rect} pixel 312 * @return {cc.Rect} 313 * @function 314 */ 315 cc.rectPixelsToPoints = cc.IS_RETINA_DISPLAY_SUPPORTED ? function (pixel) { 316 var scale = cc.contentScaleFactor(); 317 return cc.rect(pixel.x / scale, pixel.y / scale, 318 pixel.width / scale, pixel.height / scale); 319 } : function (p) { 320 return p; 321 }; 322 323 /** 324 * Converts a rect in points to pixels 325 * @param {cc.Rect} point 326 * @return {cc.Rect} 327 * @function 328 */ 329 cc.rectPointsToPixels = cc.IS_RETINA_DISPLAY_SUPPORTED ? function (point) { 330 var scale = cc.contentScaleFactor(); 331 return cc.rect(point.x * scale, point.y * scale, 332 point.width * scale, point.height * scale); 333 } : function (p) { 334 return p; 335 }; 336 337 //some gl constant variable 338 /** 339 * @constant 340 * @type Number 341 */ 342 cc.ONE = 1; 343 344 /** 345 * @constant 346 * @type Number 347 */ 348 cc.ZERO = 0; 349 350 /** 351 * @constant 352 * @type Number 353 */ 354 cc.SRC_ALPHA = 0x0302; 355 356 /** 357 * @constant 358 * @type Number 359 */ 360 cc.SRC_ALPHA_SATURATE = 0x308; 361 362 /** 363 * @constant 364 * @type Number 365 */ 366 cc.SRC_COLOR = 0x300; 367 368 /** 369 * @constant 370 * @type Number 371 */ 372 cc.DST_ALPHA = 0x304; 373 374 /** 375 * @constant 376 * @type Number 377 */ 378 cc.DST_COLOR = 0x306; 379 380 /** 381 * @constant 382 * @type Number 383 */ 384 cc.ONE_MINUS_SRC_ALPHA = 0x0303; 385 386 /** 387 * @constant 388 * @type Number 389 */ 390 cc.ONE_MINUS_SRC_COLOR = 0x301; 391 392 /** 393 * @constant 394 * @type Number 395 */ 396 cc.ONE_MINUS_DST_ALPHA = 0x305; 397 398 /** 399 * @constant 400 * @type Number 401 */ 402 cc.ONE_MINUS_DST_COLOR = 0x0307; 403 404 /** 405 * @constant 406 * @type Number 407 */ 408 cc.ONE_MINUS_CONSTANT_ALPHA = 0x8004; 409 410 /** 411 * @constant 412 * @type Number 413 */ 414 cc.ONE_MINUS_CONSTANT_COLOR = 0x8002; 415 416 /** 417 * the constant variable equals gl.LINEAR for texture 418 * @constant 419 * @type Number 420 */ 421 cc.LINEAR = 0x2601; 422 423 /** 424 * the constant variable equals gl.REPEAT for texture 425 * @constant 426 * @type Number 427 */ 428 cc.REPEAT = 0x2901; 429 430 /** 431 * the constant variable equals gl.CLAMP_TO_EDGE for texture 432 * @constant 433 * @type Number 434 */ 435 cc.CLAMP_TO_EDGE = 0x812f; 436 437 /** 438 * the constant variable equals gl.MIRRORED_REPEAT for texture 439 * @constant 440 * @type Number 441 */ 442 cc.MIRRORED_REPEAT = 0x8370; 443 444 /** 445 * default gl blend src function. Compatible with premultiplied alpha images. 446 * @constant 447 * @name cc.BLEND_SRC 448 * @type Number 449 */ 450 cc.BLEND_SRC = cc.SRC_ALPHA; 451 cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { 452 if (cc._renderType === cc.game.RENDER_TYPE_WEBGL 453 && cc.OPTIMIZE_BLEND_FUNC_FOR_PREMULTIPLIED_ALPHA) { 454 cc.BLEND_SRC = cc.ONE; 455 } 456 }); 457 458 /** 459 * default gl blend dst function. Compatible with premultiplied alpha images. 460 * @constant 461 * @type Number 462 */ 463 cc.BLEND_DST = cc.ONE_MINUS_SRC_ALPHA; 464 465 /** 466 * Check webgl error.Error will be shown in console if exists. 467 * @function 468 */ 469 cc.checkGLErrorDebug = function () { 470 if (cc.renderMode === cc.game.RENDER_TYPE_WEBGL) { 471 var _error = cc._renderContext.getError(); 472 if (_error) { 473 cc.log(cc._LogInfos.checkGLErrorDebug, _error); 474 } 475 } 476 }; 477 478 //Possible device orientations 479 /** 480 * Device oriented vertically, home button on the bottom (UIDeviceOrientationPortrait) 481 * @constant 482 * @type Number 483 */ 484 cc.DEVICE_ORIENTATION_PORTRAIT = 0; 485 486 /** 487 * Device oriented horizontally, home button on the right (UIDeviceOrientationLandscapeLeft) 488 * @constant 489 * @type Number 490 */ 491 cc.DEVICE_ORIENTATION_LANDSCAPE_LEFT = 1; 492 493 /** 494 * Device oriented vertically, home button on the top (UIDeviceOrientationPortraitUpsideDown) 495 * @constant 496 * @type Number 497 */ 498 cc.DEVICE_ORIENTATION_PORTRAIT_UPSIDE_DOWN = 2; 499 500 /** 501 * Device oriented horizontally, home button on the left (UIDeviceOrientationLandscapeRight) 502 * @constant 503 * @type Number 504 */ 505 cc.DEVICE_ORIENTATION_LANDSCAPE_RIGHT = 3; 506 507 /** 508 * In browsers, we only support 2 orientations by change window size. 509 * @constant 510 * @type Number 511 */ 512 cc.DEVICE_MAX_ORIENTATIONS = 2; 513 514 515 // ------------------- vertex attrib flags ----------------------------- 516 /** 517 * @constant 518 * @type {Number} 519 */ 520 cc.VERTEX_ATTRIB_FLAG_NONE = 0; 521 /** 522 * @constant 523 * @type {Number} 524 */ 525 cc.VERTEX_ATTRIB_FLAG_POSITION = 1 << 0; 526 /** 527 * @constant 528 * @type {Number} 529 */ 530 cc.VERTEX_ATTRIB_FLAG_COLOR = 1 << 1; 531 /** 532 * @constant 533 * @type {Number} 534 */ 535 cc.VERTEX_ATTRIB_FLAG_TEX_COORDS = 1 << 2; 536 /** 537 * @constant 538 * @type {Number} 539 */ 540 cc.VERTEX_ATTRIB_FLAG_POS_COLOR_TEX = ( cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_COLOR | cc.VERTEX_ATTRIB_FLAG_TEX_COORDS ); 541 542 /** 543 * GL server side states 544 * @constant 545 * @type {Number} 546 */ 547 cc.GL_ALL = 0; 548 549 //-------------Vertex Attributes----------- 550 /** 551 * @constant 552 * @type {Number} 553 */ 554 cc.VERTEX_ATTRIB_POSITION = 0; 555 /** 556 * @constant 557 * @type {Number} 558 */ 559 cc.VERTEX_ATTRIB_COLOR = 1; 560 /** 561 * @constant 562 * @type {Number} 563 */ 564 cc.VERTEX_ATTRIB_TEX_COORDS = 2; 565 /** 566 * @constant 567 * @type {Number} 568 */ 569 cc.VERTEX_ATTRIB_MAX = 7; 570 571 //------------Uniforms------------------ 572 /** 573 * @constant 574 * @type {Number} 575 */ 576 cc.UNIFORM_PMATRIX = 0; 577 /** 578 * @constant 579 * @type {Number} 580 */ 581 cc.UNIFORM_MVMATRIX = 1; 582 /** 583 * @constant 584 * @type {Number} 585 */ 586 cc.UNIFORM_MVPMATRIX = 2; 587 /** 588 * @constant 589 * @type {Number} 590 */ 591 cc.UNIFORM_TIME = 3; 592 /** 593 * @constant 594 * @type {Number} 595 */ 596 cc.UNIFORM_SINTIME = 4; 597 /** 598 * @constant 599 * @type {Number} 600 */ 601 cc.UNIFORM_COSTIME = 5; 602 /** 603 * @constant 604 * @type {Number} 605 */ 606 cc.UNIFORM_RANDOM01 = 6; 607 /** 608 * @constant 609 * @type {Number} 610 */ 611 cc.UNIFORM_SAMPLER = 7; 612 /** 613 * @constant 614 * @type {Number} 615 */ 616 cc.UNIFORM_MAX = 8; 617 618 //------------Shader Name--------------- 619 /** 620 * @constant 621 * @type {String} 622 */ 623 cc.SHADER_POSITION_TEXTURECOLOR = "ShaderPositionTextureColor"; 624 /** 625 * @constant 626 * @type {String} 627 */ 628 cc.SHADER_SPRITE_POSITION_TEXTURECOLOR = "ShaderSpritePositionTextureColor"; 629 /** 630 * @constant 631 * @type {String} 632 */ 633 cc.SHADER_POSITION_TEXTURECOLORALPHATEST = "ShaderPositionTextureColorAlphaTest"; 634 /** 635 * @constant 636 * @type {String} 637 */ 638 cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST = "ShaderSpritePositionTextureColorAlphaTest"; 639 /** 640 * @constant 641 * @type {String} 642 */ 643 cc.SHADER_POSITION_COLOR = "ShaderPositionColor"; 644 /** 645 * @constant 646 * @type {String} 647 */ 648 cc.SHADER_SPRITE_POSITION_COLOR = "ShaderSpritePositionColor"; 649 /** 650 * @constant 651 * @type {String} 652 */ 653 cc.SHADER_POSITION_TEXTURE = "ShaderPositionTexture"; 654 /** 655 * @constant 656 * @type {String} 657 */ 658 cc.SHADER_POSITION_TEXTURE_UCOLOR = "ShaderPositionTexture_uColor"; 659 /** 660 * @constant 661 * @type {String} 662 */ 663 cc.SHADER_POSITION_TEXTUREA8COLOR = "ShaderPositionTextureA8Color"; 664 /** 665 * @constant 666 * @type {String} 667 */ 668 cc.SHADER_POSITION_UCOLOR = "ShaderPosition_uColor"; 669 /** 670 * @constant 671 * @type {String} 672 */ 673 cc.SHADER_POSITION_LENGTHTEXTURECOLOR = "ShaderPositionLengthTextureColor"; 674 675 //------------uniform names---------------- 676 /** 677 * @constant 678 * @type {String} 679 */ 680 cc.UNIFORM_PMATRIX_S = "CC_PMatrix"; 681 /** 682 * @constant 683 * @type {String} 684 */ 685 cc.UNIFORM_MVMATRIX_S = "CC_MVMatrix"; 686 /** 687 * @constant 688 * @type {String} 689 */ 690 cc.UNIFORM_MVPMATRIX_S = "CC_MVPMatrix"; 691 /** 692 * @constant 693 * @type {String} 694 */ 695 cc.UNIFORM_TIME_S = "CC_Time"; 696 /** 697 * @constant 698 * @type {String} 699 */ 700 cc.UNIFORM_SINTIME_S = "CC_SinTime"; 701 /** 702 * @constant 703 * @type {String} 704 */ 705 cc.UNIFORM_COSTIME_S = "CC_CosTime"; 706 /** 707 * @constant 708 * @type {String} 709 */ 710 cc.UNIFORM_RANDOM01_S = "CC_Random01"; 711 /** 712 * @constant 713 * @type {String} 714 */ 715 cc.UNIFORM_SAMPLER_S = "CC_Texture0"; 716 /** 717 * @constant 718 * @type {String} 719 */ 720 cc.UNIFORM_ALPHA_TEST_VALUE_S = "CC_alpha_value"; 721 722 //------------Attribute names-------------- 723 /** 724 * @constant 725 * @type {String} 726 */ 727 cc.ATTRIBUTE_NAME_COLOR = "a_color"; 728 /** 729 * @constant 730 * @type {String} 731 */ 732 cc.ATTRIBUTE_NAME_POSITION = "a_position"; 733 /** 734 * @constant 735 * @type {String} 736 */ 737 cc.ATTRIBUTE_NAME_TEX_COORD = "a_texCoord"; 738 /** 739 * @constant 740 * @type {String} 741 */ 742 cc.ATTRIBUTE_NAME_MVMAT = "a_mvMatrix"; 743 744 745 /** 746 * default size for font size 747 * @constant 748 * @type Number 749 */ 750 cc.ITEM_SIZE = 32; 751 752 /** 753 * default tag for current item 754 * @constant 755 * @type Number 756 */ 757 cc.CURRENT_ITEM = 0xc0c05001; 758 /** 759 * default tag for zoom action tag 760 * @constant 761 * @type Number 762 */ 763 cc.ZOOM_ACTION_TAG = 0xc0c05002; 764 /** 765 * default tag for normal 766 * @constant 767 * @type Number 768 */ 769 cc.NORMAL_TAG = 8801; 770 771 /** 772 * default selected tag 773 * @constant 774 * @type Number 775 */ 776 cc.SELECTED_TAG = 8802; 777 778 /** 779 * default disabled tag 780 * @constant 781 * @type Number 782 */ 783 cc.DISABLE_TAG = 8803; 784 785 786 // Array utils 787 788 /** 789 * Verify Array's Type 790 * @param {Array} arr 791 * @param {function} type 792 * @return {Boolean} 793 * @function 794 */ 795 cc.arrayVerifyType = function (arr, type) { 796 if (arr && arr.length > 0) { 797 for (var i = 0; i < arr.length; i++) { 798 if (!(arr[i] instanceof type)) { 799 cc.log("element type is wrong!"); 800 return false; 801 } 802 } 803 } 804 return true; 805 }; 806 807 /** 808 * Searches for the first occurrence of object and removes it. If object is not found the function has no effect. 809 * @function 810 * @param {Array} arr Source Array 811 * @param {*} delObj remove object 812 */ 813 cc.arrayRemoveObject = function (arr, delObj) { 814 for (var i = 0, l = arr.length; i < l; i++) { 815 if (arr[i] === delObj) { 816 arr.splice(i, 1); 817 break; 818 } 819 } 820 }; 821 822 /** 823 * Removes from arr all values in minusArr. For each Value in minusArr, the first matching instance in arr will be removed. 824 * @function 825 * @param {Array} arr Source Array 826 * @param {Array} minusArr minus Array 827 */ 828 cc.arrayRemoveArray = function (arr, minusArr) { 829 for (var i = 0, l = minusArr.length; i < l; i++) { 830 cc.arrayRemoveObject(arr, minusArr[i]); 831 } 832 }; 833 834 /** 835 * Inserts some objects at index 836 * @function 837 * @param {Array} arr 838 * @param {Array} addObjs 839 * @param {Number} index 840 * @return {Array} 841 */ 842 cc.arrayAppendObjectsToIndex = function(arr, addObjs,index){ 843 arr.splice.apply(arr, [index, 0].concat(addObjs)); 844 return arr; 845 }; 846 847 /** 848 * Copy an array's item to a new array (its performance is better than Array.slice) 849 * @param {Array} arr 850 * @return {Array} 851 */ 852 cc.copyArray = function(arr){ 853 var i, len = arr.length, arr_clone = new Array(len); 854 for (i = 0; i < len; i += 1) 855 arr_clone[i] = arr[i]; 856 return arr_clone; 857 }; 858