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