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 ((typeof ref) == 'object' && (typeof ref.x) != 'undefined' && (typeof ref.y) != 'undefined') {
 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  * default gl blend src function. Compatible with premultiplied alpha images.
171  * @constant
172  * @type Number
173  */
174 cc.BLEND_SRC = cc.OPTIMIZE_BLEND_FUNC_FOR_PREMULTIPLIED_ALPHA ? 1 : 0x0302;
175 
176 /**
177  * default gl blend dst function. Compatible with premultiplied alpha images.
178  * @constant
179  * @type Number
180  */
181 cc.BLEND_DST = 0x0303;
182 
183 /**
184  * Helpful macro that setups the GL server state, the correct GL program and sets the Model View Projection matrix
185  * @param {cc.Node} node setup node
186  * @function
187  */
188 cc.nodeDrawSetup = function (node) {
189     //cc.glEnable(node._glServerState);
190     if (node._shaderProgram) {
191         //cc._renderContext.useProgram(node._shaderProgram._programObj);
192         node._shaderProgram.use();
193         node._shaderProgram.setUniformForModelViewAndProjectionMatrixWithMat4();
194     }
195 };
196 
197 /**
198  * <p>
199  *     GL states that are enabled:<br/>
200  *       - GL_TEXTURE_2D<br/>
201  *       - GL_VERTEX_ARRAY<br/>
202  *       - GL_TEXTURE_COORD_ARRAY<br/>
203  *       - GL_COLOR_ARRAY<br/>
204  * </p>
205  * @function
206  */
207 cc.enableDefaultGLStates = function () {
208     //TODO OPENGL STUFF
209     /*
210      glEnableClientState(GL_VERTEX_ARRAY);
211      glEnableClientState(GL_COLOR_ARRAY);
212      glEnableClientState(GL_TEXTURE_COORD_ARRAY);
213      glEnable(GL_TEXTURE_2D);*/
214 };
215 
216 /**
217  * <p>
218  *   Disable default GL states:<br/>
219  *     - GL_TEXTURE_2D<br/>
220  *     - GL_TEXTURE_COORD_ARRAY<br/>
221  *     - GL_COLOR_ARRAY<br/>
222  * </p>
223  * @function
224  */
225 cc.disableDefaultGLStates = function () {
226     //TODO OPENGL
227     /*
228      glDisable(GL_TEXTURE_2D);
229      glDisableClientState(GL_COLOR_ARRAY);
230      glDisableClientState(GL_TEXTURE_COORD_ARRAY);
231      glDisableClientState(GL_VERTEX_ARRAY);
232      */
233 };
234 
235 /**
236  * <p>
237  *  Increments the GL Draws counts by one.<br/>
238  *  The number of calls per frame are displayed on the screen when the CCDirector's stats are enabled.<br/>
239  * </p>
240  * @param {Number} addNumber
241  * @function
242  */
243 cc.incrementGLDraws = function (addNumber) {
244     cc.g_NumberOfDraws += addNumber;
245 };
246 
247 /**
248  * @constant
249  * @type Number
250  */
251 cc.FLT_EPSILON = 0.0000001192092896;
252 
253 /**
254  * <p>
255  *     On Mac it returns 1;<br/>
256  *     On iPhone it returns 2 if RetinaDisplay is On. Otherwise it returns 1
257  * </p>
258  * @return {Number}
259  * @function
260  */
261 cc.contentScaleFactor = cc.IS_RETINA_DISPLAY_SUPPORTED ? function () {
262     return cc.director.getContentScaleFactor();
263 } : function () {
264     return 1;
265 };
266 
267 /**
268  * Converts a Point in points to pixels
269  * @param {cc.Point} points
270  * @return {cc.Point}
271  * @function
272  */
273 cc.pointPointsToPixels = function (points) {
274     var scale = cc.contentScaleFactor();
275     return cc.p(points.x * scale, points.y * scale);
276 };
277 
278 /**
279  * Converts a Point in pixels to points
280  * @param {cc.Rect} pixels
281  * @return {cc.Point}
282  * @function
283  */
284 cc.pointPixelsToPoints = function (pixels) {
285 	var scale = cc.contentScaleFactor();
286 	return cc.p(pixels.x / scale, pixels.y / scale);
287 };
288 
289 cc._pointPixelsToPointsOut = function(pixels, outPoint){
290 	var scale = cc.contentScaleFactor();
291 	outPoint.x = pixels.x / scale;
292 	outPoint.y = pixels.y / scale;
293 };
294 
295 /**
296  * Converts a Size in points to pixels
297  * @param {cc.Size} sizeInPoints
298  * @return {cc.Size}
299  * @function
300  */
301 cc.sizePointsToPixels = function (sizeInPoints) {
302     var scale = cc.contentScaleFactor();
303     return cc.size(sizeInPoints.width * scale, sizeInPoints.height * scale);
304 };
305 
306 /**
307  * Converts a size in pixels to points
308  * @param {cc.Size} sizeInPixels
309  * @return {cc.Size}
310  * @function
311  */
312 cc.sizePixelsToPoints = function (sizeInPixels) {
313     var scale = cc.contentScaleFactor();
314     return cc.size(sizeInPixels.width / scale, sizeInPixels.height / scale);
315 };
316 
317 cc._sizePixelsToPointsOut = function (sizeInPixels, outSize) {
318     var scale = cc.contentScaleFactor();
319     outSize.width = sizeInPixels.width / scale;
320     outSize.height = sizeInPixels.height / scale;
321 };
322 
323 /**
324  * Converts a rect in pixels to points
325  * @param {cc.Rect} pixel
326  * @return {cc.Rect}
327  * @function
328  */
329 cc.rectPixelsToPoints = cc.IS_RETINA_DISPLAY_SUPPORTED ? function (pixel) {
330     var scale = cc.contentScaleFactor();
331     return cc.rect(pixel.x / scale, pixel.y / scale,
332         pixel.width / scale, pixel.height / scale);
333 } : function (p) {
334     return p;
335 };
336 
337 /**
338  * Converts a rect in points to pixels
339  * @param {cc.Rect} point
340  * @return {cc.Rect}
341  * @function
342  */
343 cc.rectPointsToPixels = cc.IS_RETINA_DISPLAY_SUPPORTED ? function (point) {
344    var scale = cc.contentScaleFactor();
345     return cc.rect(point.x * scale, point.y * scale,
346         point.width * scale, point.height * scale);
347 } : function (p) {
348     return p;
349 };
350 
351 /**
352  * @constant
353  * @type Number
354  */
355 cc.ONE = 1;
356 
357 /**
358  * @constant
359  * @type Number
360  */
361 cc.ZERO = 0;
362 
363 /**
364  * @constant
365  * @type Number
366  */
367 cc.SRC_ALPHA = 0x0302;
368 
369 /**
370  * @constant
371  * @type Number
372  */
373 cc.SRC_ALPHA_SATURATE = 0x308;
374 
375 /**
376  * @constant
377  * @type Number
378  */
379 cc.SRC_COLOR = 0x300;
380 
381 /**
382  * @constant
383  * @type Number
384  */
385 cc.DST_ALPHA = 0x304;
386 
387 /**
388  * @constant
389  * @type Number
390  */
391 cc.DST_COLOR = 0x306;
392 
393 /**
394  * @constant
395  * @type Number
396  */
397 cc.ONE_MINUS_SRC_ALPHA = 0x0303;
398 
399 /**
400  * @constant
401  * @type Number
402  */
403 cc.ONE_MINUS_SRC_COLOR = 0x301;
404 
405 /**
406  * @constant
407  * @type Number
408  */
409 cc.ONE_MINUS_DST_ALPHA = 0x305;
410 
411 /**
412  * @constant
413  * @type Number
414  */
415 cc.ONE_MINUS_DST_COLOR = 0x0307;
416 
417 /**
418  * @constant
419  * @type Number
420  */
421 cc.ONE_MINUS_CONSTANT_ALPHA	= 0x8004;
422 
423 /**
424  * @constant
425  * @type Number
426  */
427 cc.ONE_MINUS_CONSTANT_COLOR	= 0x8002;
428 
429 /**
430  * Check webgl error.Error will be shown in console if exists.
431  * @function
432  */
433 cc.checkGLErrorDebug = function () {
434     if (cc.renderMode == cc._RENDER_TYPE_WEBGL) {
435         var _error = cc._renderContext.getError();
436         if (_error) {
437             cc.log(cc._LogInfos.checkGLErrorDebug, _error);
438         }
439     }
440 };
441 
442 //Possible device orientations
443 /**
444  * Device oriented vertically, home button on the bottom (UIDeviceOrientationPortrait)
445  * @constant
446  * @type Number
447  */
448 cc.DEVICE_ORIENTATION_PORTRAIT = 0;
449 
450 /**
451  * Device oriented horizontally, home button on the right (UIDeviceOrientationLandscapeLeft)
452  * @constant
453  * @type Number
454  */
455 cc.DEVICE_ORIENTATION_LANDSCAPE_LEFT = 1;
456 
457 /**
458  * Device oriented vertically, home button on the top (UIDeviceOrientationPortraitUpsideDown)
459  * @constant
460  * @type Number
461  */
462 cc.DEVICE_ORIENTATION_PORTRAIT_UPSIDE_DOWN = 2;
463 
464 /**
465  * Device oriented horizontally, home button on the left (UIDeviceOrientationLandscapeRight)
466  * @constant
467  * @type Number
468  */
469 cc.DEVICE_ORIENTATION_LANDSCAPE_RIGHT = 3;
470 
471 /**
472  * In browsers, we only support 2 orientations by change window size.
473  * @constant
474  * @type Number
475  */
476 cc.DEVICE_MAX_ORIENTATIONS = 2;
477 
478 
479 // ------------------- vertex attrib flags -----------------------------
480 /**
481  * @constant
482  * @type {Number}
483  */
484 cc.VERTEX_ATTRIB_FLAG_NONE = 0;
485 /**
486  * @constant
487  * @type {Number}
488  */
489 cc.VERTEX_ATTRIB_FLAG_POSITION = 1 << 0;
490 /**
491  * @constant
492  * @type {Number}
493  */
494 cc.VERTEX_ATTRIB_FLAG_COLOR = 1 << 1;
495 /**
496  * @constant
497  * @type {Number}
498  */
499 cc.VERTEX_ATTRIB_FLAG_TEX_COORDS = 1 << 2;
500 /**
501  * @constant
502  * @type {Number}
503  */
504 cc.VERTEX_ATTRIB_FLAG_POS_COLOR_TEX = ( cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_COLOR | cc.VERTEX_ATTRIB_FLAG_TEX_COORDS );
505 
506 /**
507  * GL server side states
508  * @constant
509  * @type {Number}
510  */
511 cc.GL_ALL = 0;
512 
513 //-------------Vertex Attributes-----------
514 /**
515  * @constant
516  * @type {Number}
517  */
518 cc.VERTEX_ATTRIB_POSITION = 0;
519 /**
520  * @constant
521  * @type {Number}
522  */
523 cc.VERTEX_ATTRIB_COLOR = 1;
524 /**
525  * @constant
526  * @type {Number}
527  */
528 cc.VERTEX_ATTRIB_TEX_COORDS = 2;
529 /**
530  * @constant
531  * @type {Number}
532  */
533 cc.VERTEX_ATTRIB_MAX = 3;
534 
535 //------------Uniforms------------------
536 /**
537  * @constant
538  * @type {Number}
539  */
540 cc.UNIFORM_PMATRIX = 0;
541 /**
542  * @constant
543  * @type {Number}
544  */
545 cc.UNIFORM_MVMATRIX = 1;
546 /**
547  * @constant
548  * @type {Number}
549  */
550 cc.UNIFORM_MVPMATRIX = 2;
551 /**
552  * @constant
553  * @type {Number}
554  */
555 cc.UNIFORM_TIME = 3;
556 /**
557  * @constant
558  * @type {Number}
559  */
560 cc.UNIFORM_SINTIME = 4;
561 /**
562  * @constant
563  * @type {Number}
564  */
565 cc.UNIFORM_COSTIME = 5;
566 /**
567  * @constant
568  * @type {Number}
569  */
570 cc.UNIFORM_RANDOM01 = 6;
571 /**
572  * @constant
573  * @type {Number}
574  */
575 cc.UNIFORM_SAMPLER = 7;
576 /**
577  * @constant
578  * @type {Number}
579  */
580 cc.UNIFORM_MAX = 8;
581 
582 //------------Shader Name---------------
583 /**
584  * @constant
585  * @type {String}
586  */
587 cc.SHADER_POSITION_TEXTURECOLOR = "ShaderPositionTextureColor";
588 /**
589  * @constant
590  * @type {String}
591  */
592 cc.SHADER_POSITION_TEXTURECOLORALPHATEST = "ShaderPositionTextureColorAlphaTest";
593 /**
594  * @constant
595  * @type {String}
596  */
597 cc.SHADER_POSITION_COLOR = "ShaderPositionColor";
598 /**
599  * @constant
600  * @type {String}
601  */
602 cc.SHADER_POSITION_TEXTURE = "ShaderPositionTexture";
603 /**
604  * @constant
605  * @type {String}
606  */
607 cc.SHADER_POSITION_TEXTURE_UCOLOR = "ShaderPositionTexture_uColor";
608 /**
609  * @constant
610  * @type {String}
611  */
612 cc.SHADER_POSITION_TEXTUREA8COLOR = "ShaderPositionTextureA8Color";
613 /**
614  * @constant
615  * @type {String}
616  */
617 cc.SHADER_POSITION_UCOLOR = "ShaderPosition_uColor";
618 /**
619  * @constant
620  * @type {String}
621  */
622 cc.SHADER_POSITION_LENGTHTEXTURECOLOR = "ShaderPositionLengthTextureColor";
623 
624 //------------uniform names----------------
625 /**
626  * @constant
627  * @type {String}
628  */
629 cc.UNIFORM_PMATRIX_S = "CC_PMatrix";
630 /**
631  * @constant
632  * @type {String}
633  */
634 cc.UNIFORM_MVMATRIX_S = "CC_MVMatrix";
635 /**
636  * @constant
637  * @type {String}
638  */
639 cc.UNIFORM_MVPMATRIX_S = "CC_MVPMatrix";
640 /**
641  * @constant
642  * @type {String}
643  */
644 cc.UNIFORM_TIME_S = "CC_Time";
645 /**
646  * @constant
647  * @type {String}
648  */
649 cc.UNIFORM_SINTIME_S = "CC_SinTime";
650 /**
651  * @constant
652  * @type {String}
653  */
654 cc.UNIFORM_COSTIME_S = "CC_CosTime";
655 /**
656  * @constant
657  * @type {String}
658  */
659 cc.UNIFORM_RANDOM01_S = "CC_Random01";
660 /**
661  * @constant
662  * @type {String}
663  */
664 cc.UNIFORM_SAMPLER_S = "CC_Texture0";
665 /**
666  * @constant
667  * @type {String}
668  */
669 cc.UNIFORM_ALPHA_TEST_VALUE_S = "CC_alpha_value";
670 
671 //------------Attribute names--------------
672 /**
673  * @constant
674  * @type {String}
675  */
676 cc.ATTRIBUTE_NAME_COLOR = "a_color";
677 /**
678  * @constant
679  * @type {String}
680  */
681 cc.ATTRIBUTE_NAME_POSITION = "a_position";
682 /**
683  * @constant
684  * @type {String}
685  */
686 cc.ATTRIBUTE_NAME_TEX_COORD = "a_texCoord";
687 
688 
689 /**
690  * default size for font size
691  * @constant
692  * @type Number
693  */
694 cc.ITEM_SIZE = 32;
695 
696 /**
697  * default tag for current item
698  * @constant
699  * @type Number
700  */
701 cc.CURRENT_ITEM = 0xc0c05001;
702 /**
703  * default tag for zoom action tag
704  * @constant
705  * @type Number
706  */
707 cc.ZOOM_ACTION_TAG = 0xc0c05002;
708 /**
709  * default tag for normal
710  * @constant
711  * @type Number
712  */
713 cc.NORMAL_TAG = 8801;
714 
715 /**
716  * default selected tag
717  * @constant
718  * @type Number
719  */
720 cc.SELECTED_TAG = 8802;
721 
722 /**
723  * default disabled tag
724  * @constant
725  * @type Number
726  */
727 cc.DISABLE_TAG = 8803;
728 
729 
730 // Array utils
731 
732 /**
733  * Verify Array's Type
734  * @param {Array} arr
735  * @param {function} type
736  * @return {Boolean}
737  * @function
738  */
739 cc.arrayVerifyType = function (arr, type) {
740     if (arr && arr.length > 0) {
741         for (var i = 0; i < arr.length; i++) {
742             if (!(arr[i] instanceof  type)) {
743                 cc.log("element type is wrong!");
744                 return false;
745             }
746         }
747     }
748     return true;
749 };
750 
751 /**
752  * Searches for the first occurance of object and removes it. If object is not found the function has no effect.
753  * @function
754  * @param {Array} arr Source Array
755  * @param {*} delObj  remove object
756  */
757 cc.arrayRemoveObject = function (arr, delObj) {
758     for (var i = 0, l = arr.length; i < l; i++) {
759         if (arr[i] == delObj) {
760             arr.splice(i, 1);
761             break;
762         }
763     }
764 };
765 
766 /**
767  * Removes from arr all values in minusArr. For each Value in minusArr, the first matching instance in arr will be removed.
768  * @function
769  * @param {Array} arr Source Array
770  * @param {Array} minusArr minus Array
771  */
772 cc.arrayRemoveArray = function (arr, minusArr) {
773     for (var i = 0, l = minusArr.length; i < l; i++) {
774         cc.arrayRemoveObject(arr, minusArr[i]);
775     }
776 };
777 
778 /**
779  * Inserts some objects at index
780  * @function
781  * @param {Array} arr
782  * @param {Array} addObjs
783  * @param {Number} index
784  * @return {Array}
785  */
786 cc.arrayAppendObjectsToIndex = function(arr, addObjs,index){
787     arr.splice.apply(arr, [index, 0].concat(addObjs));
788     return arr;
789 };
790 
791 /**
792  * Copy an array's item to a new array (its performance is better than Array.slice)
793  * @param {Array} arr
794  * @return {Array}
795  */
796 cc.copyArray = function(arr){
797     var i, len = arr.length, arr_clone = new Array(len);
798     for (i = 0; i < len; i += 1)
799         arr_clone[i] = arr[i];
800     return arr_clone;
801 };