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  * cc.Waves3D action
 29  * @class
 30  * @extends cc.Grid3DAction
 31  */
 32 cc.Waves3D = cc.Grid3DAction.extend(/** @lends cc.Waves3D# */{
 33     _waves: 0,
 34     _amplitude: 0,
 35     _amplitudeRate: 0,
 36 
 37 	/**
 38 	 * Create a wave 3d action with duration, grid size, waves and amplitude
 39 	 * @param {Number} duration
 40 	 * @param {cc.Size} gridSize
 41 	 * @param {Number} waves
 42 	 * @param {Number} amplitude
 43 	 */
 44     ctor:function (duration, gridSize, waves, amplitude) {
 45         cc.GridAction.prototype.ctor.call(this);
 46 		amplitude !== undefined && this.initWithDuration(duration, gridSize, waves, amplitude);
 47     },
 48 
 49     /**
 50      * get Amplitude
 51      * @return {Number}
 52      */
 53     getAmplitude:function () {
 54         return this._amplitude;
 55     },
 56 
 57     /**
 58      * set Amplitude
 59      * @param {Number} amplitude
 60      */
 61     setAmplitude:function (amplitude) {
 62         this._amplitude = amplitude;
 63     },
 64 
 65     /**
 66      * get Amplitude Rate
 67      * @return {Number}
 68      */
 69     getAmplitudeRate:function () {
 70         return this._amplitudeRate;
 71     },
 72 
 73     /**
 74      * set Amplitude Rate
 75      * @param {Number} amplitudeRate
 76      */
 77     setAmplitudeRate:function (amplitudeRate) {
 78         this._amplitudeRate = amplitudeRate;
 79     },
 80 
 81     /**
 82      * initializes an action with duration, grid size, waves and amplitude
 83      * @param {Number} duration
 84      * @param {cc.Size} gridSize
 85      * @param {Number} waves
 86      * @param {Number} amplitude
 87      * @return {Boolean}
 88      */
 89     initWithDuration:function (duration, gridSize, waves, amplitude) {
 90         if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
 91             this._waves = waves;
 92             this._amplitude = amplitude;
 93             this._amplitudeRate = 1.0;
 94             return true;
 95         }
 96         return false;
 97     },
 98 
 99     update:function (time) {
100         var locGridSize = this._gridSize;
101         var locAmplitude = this._amplitude, locPos = cc.p(0, 0);
102         var locAmplitudeRate = this._amplitudeRate, locWaves = this._waves;
103         for (var i = 0; i < locGridSize.width + 1; ++i) {
104             for (var j = 0; j < locGridSize.height + 1; ++j) {
105                 locPos.x = i;
106                 locPos.y = j;
107                 var v = this.originalVertex(locPos);
108                 v.z += (Math.sin(Math.PI * time * locWaves * 2 + (v.y + v.x) * 0.01) * locAmplitude * locAmplitudeRate);
109                 //cc.log("v.z offset is" + (Math.sin(Math.PI * time * this._waves * 2 + (v.y + v.x) * 0.01) * this._amplitude * this._amplitudeRate));
110                 this.setVertex(locPos, v);
111             }
112         }
113     }
114 });
115 
116 /**
117  * Create a wave 3d action with duration, grid size, waves and amplitude
118  * @param {Number} duration
119  * @param {cc.Size} gridSize
120  * @param {Number} waves
121  * @param {Number} amplitude
122  */
123 cc.Waves3D.create = function (duration, gridSize, waves, amplitude) {
124     return new cc.Waves3D(duration, gridSize, waves, amplitude);
125 };
126 
127 /**
128  * cc.FlipX3D action
129  * @class
130  * @extends cc.Grid3DAction
131  */
132 cc.FlipX3D = cc.Grid3DAction.extend(/** @lends cc.FlipX3D# */{
133 
134 	/**
135 	 * Create a Flip X 3D action with duration
136 	 * Constructor of cc.FlipX3D
137 	 * @param {Number} duration
138 	 */
139 	ctor: function(duration) {
140 		if (duration !== undefined)
141 			cc.GridAction.prototype.ctor.call(this, duration, cc.size(1, 1));
142 		else cc.GridAction.prototype.ctor.call(this);
143 	},
144 
145     /**
146      * initializes the action with duration
147      * @param {Number} duration
148      * @return {Boolean}
149      */
150     initWithDuration:function (duration) {
151         return cc.Grid3DAction.prototype.initWithDuration.call(this, duration, cc.size(1, 1));
152     },
153 
154     /**
155      * initializes the action with gridSize and duration
156      * @param {cc.Size} gridSize
157      * @param {Number} duration
158      * @return {Boolean}
159      */
160     initWithSize:function (gridSize, duration) {
161         if (gridSize.width != 1 || gridSize.height != 1) {
162             // Grid size must be (1,1)
163             cc.log("Grid size must be (1,1)");
164             return false;
165         }
166         return  cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize);
167     },
168 
169     update:function (time) {
170         var angle = Math.PI * time; // 180 degrees
171         var mz = Math.sin(angle);
172         angle = angle / 2.0; // x calculates degrees from 0 to 90
173         var mx = Math.cos(angle);
174 
175         var diff = new cc.Vertex3F();
176         var tempVer = cc.p(0, 0);
177         tempVer.x = tempVer.y = 1;
178         var v0 = this.originalVertex(tempVer);
179         tempVer.x = tempVer.y = 0;
180         var v1 = this.originalVertex(tempVer);
181 
182         var x0 = v0.x;
183         var x1 = v1.x;
184         var x;
185         var a, b, c, d;
186 
187         if (x0 > x1) {
188             // Normal Grid
189             a = cc.p(0, 0);
190             b = cc.p(0, 1);
191             c = cc.p(1, 0);
192             d = cc.p(1, 1);
193             x = x0;
194         } else {
195             // Reversed Grid
196             c = cc.p(0, 0);
197             d = cc.p(0, 1);
198             a = cc.p(1, 0);
199             b = cc.p(1, 1);
200             x = x1;
201         }
202 
203         diff.x = ( x - x * mx );
204         diff.z = Math.abs(parseFloat((x * mz) / 4.0));
205 
206         // bottom-left
207         var v = this.originalVertex(a);
208         v.x = diff.x;
209         v.z += diff.z;
210         this.setVertex(a, v);
211 
212         // upper-left
213         v = this.originalVertex(b);
214         v.x = diff.x;
215         v.z += diff.z;
216         this.setVertex(b, v);
217 
218         // bottom-right
219         v = this.originalVertex(c);
220         v.x -= diff.x;
221         v.z -= diff.z;
222         this.setVertex(c, v);
223 
224         // upper-right
225         v = this.originalVertex(d);
226         v.x -= diff.x;
227         v.z -= diff.z;
228         this.setVertex(d, v);
229     }
230 });
231 
232 /**
233  * Create a Flip X 3D action with duration
234  * @param {Number} duration
235  * @return {cc.FlipX3D}
236  */
237 cc.FlipX3D.create = function (duration) {
238     return new cc.FlipX3D(duration);
239 };
240 
241 /**
242  * cc.FlipY3D action
243  * @class
244  * @extends cc.FlipX3D
245  */
246 cc.FlipY3D = cc.FlipX3D.extend(/** @lends cc.FlipY3D# */{
247 
248 	/**
249 	 * Create a flip Y 3d action with duration
250 	 * Constructor of cc.FlipY3D
251 	 * @param {Number} duration
252 	 */
253 	ctor: function(duration) {
254 		if (duration !== undefined)
255 			cc.GridAction.prototype.ctor.call(this, duration, cc.size(1, 1));
256 		else cc.GridAction.prototype.ctor.call(this);
257 	},
258 
259     update:function (time) {
260         var angle = Math.PI * time; // 180 degrees
261         var mz = Math.sin(angle);
262         angle = angle / 2.0;     // x calculates degrees from 0 to 90
263         var my = Math.cos(angle);
264 
265         var diff = new cc.Vertex3F();
266 
267         var tempP = cc.p(0, 0);
268         tempP.x = tempP.y = 1;
269         var v0 = this.originalVertex(tempP);
270         tempP.x = tempP.y = 0;
271         var v1 = this.originalVertex(tempP);
272 
273         var y0 = v0.y;
274         var y1 = v1.y;
275         var y;
276         var a, b, c, d;
277 
278         if (y0 > y1) {
279             // Normal Grid
280             a = cc.p(0, 0);
281             b = cc.p(0, 1);
282             c = cc.p(1, 0);
283             d = cc.p(1, 1);
284             y = y0;
285         } else {
286             // Reversed Grid
287             b = cc.p(0, 0);
288             a = cc.p(0, 1);
289             d = cc.p(1, 0);
290             c = cc.p(1, 1);
291             y = y1;
292         }
293 
294         diff.y = y - y * my;
295         diff.z = Math.abs(parseFloat(y * mz) / 4.0);
296 
297         // bottom-left
298         var v = this.originalVertex(a);
299         v.y = diff.y;
300         v.z += diff.z;
301         this.setVertex(a, v);
302 
303         // upper-left
304         v = this.originalVertex(b);
305         v.y -= diff.y;
306         v.z -= diff.z;
307         this.setVertex(b, v);
308 
309         // bottom-right
310         v = this.originalVertex(c);
311         v.y = diff.y;
312         v.z += diff.z;
313         this.setVertex(c, v);
314 
315         // upper-right
316         v = this.originalVertex(d);
317         v.y -= diff.y;
318         v.z -= diff.z;
319         this.setVertex(d, v);
320     }
321 });
322 
323 /**
324  * Create a flip Y 3d action with duration
325  * @param {Number} duration
326  * @return {cc.FlipY3D}
327  */
328 cc.FlipY3D.create = function (duration) {
329     return new cc.FlipY3D(duration);
330 };
331 
332 /**
333  * cc.Lens3D action
334  * @class
335  * @extends cc.FlipX3D
336  */
337 cc.Lens3D = cc.Grid3DAction.extend(/** @lends cc.Lens3D# */{
338     /* lens center position */
339     _position:null,
340     _radius:0,
341     /** lens effect. Defaults to 0.7 - 0 means no effect, 1 is very strong effect */
342     _lensEffect:0,
343     /** lens is concave. (true = concave, false = convex) default is convex i.e. false */
344     _concave:false,
345     _dirty:false,
346 
347 	/**
348 	 * creates a lens 3d action with center position, radius
349 	 * Constructor of cc.Lens3D
350 	 * @param {Number} duration
351 	 * @param {cc.Size} gridSize
352 	 * @param {cc.Point} position
353 	 * @param {Number} radius
354 	 */
355     ctor:function (duration, gridSize, position, radius) {
356         cc.GridAction.prototype.ctor.call(this);
357 
358         this._position = cc.p(0, 0);
359 		radius !== undefined && this.initWithDuration(duration, gridSize, position, radius);
360     },
361 
362     /**
363      * Get lens center position
364      * @return {Number}
365      */
366     getLensEffect:function () {
367         return this._lensEffect;
368     },
369 
370     /**
371      * Set lens center position
372      * @param {Number} lensEffect
373      */
374     setLensEffect:function (lensEffect) {
375         this._lensEffect = lensEffect;
376     },
377 
378     /**
379      * Set whether lens is concave
380      * @param {Boolean} concave
381      */
382     setConcave:function (concave) {
383         this._concave = concave;
384     },
385 
386     /**
387      * get Position
388      * @return {cc.Point}
389      */
390     getPosition:function () {
391         return this._position;
392     },
393 
394     /**
395      * set Position
396      * @param {cc.Point} position
397      */
398     setPosition:function (position) {
399         if (!cc.pointEqualToPoint(position, this._position)) {
400             this._position.x = position.x;
401             this._position.y = position.y;
402             this._dirty = true;
403         }
404     },
405 
406     /**
407      * initializes the action with center position, radius, a grid size and duration
408      * @param {Number} duration
409      * @param {cc.Size} gridSize
410      * @param {cc.Point} position
411      * @param {Number} radius
412      * @return {Boolean}
413      */
414     initWithDuration:function (duration, gridSize, position, radius) {
415         if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
416             this.setPosition(position);
417             this._radius = radius;
418             this._lensEffect = 0.7;
419             this._dirty = true;
420             return true;
421         }
422         return false;
423     },
424 
425     update:function (time) {
426         if (this._dirty) {
427             var locGridSizeWidth = this._gridSize.width, locGridSizeHeight = this._gridSize.height;
428             var locRadius = this._radius, locLensEffect = this._lensEffect;
429             var locPos = cc.p(0, 0);
430             var vect = cc.p(0, 0);
431             var v, r, l, new_r, pre_log;
432             for (var i = 0; i < locGridSizeWidth + 1; ++i) {
433                 for (var j = 0; j < locGridSizeHeight + 1; ++j) {
434                     locPos.x = i;
435                     locPos.y = j;
436                     v = this.originalVertex(locPos);
437                     vect.x = this._position.x - v.x;
438                     vect.y = this._position.y - v.y;
439                     r = cc.pLength(vect);
440 
441                     if (r < locRadius) {
442                         r = locRadius - r;
443                         pre_log = r / locRadius;
444                         if (pre_log == 0)
445                             pre_log = 0.001;
446 
447                         l = Math.log(pre_log) * locLensEffect;
448                         new_r = Math.exp(l) * locRadius;
449 
450                         r = cc.pLength(vect);
451                         if (r > 0) {
452                             vect.x = vect.x / r;
453                             vect.y = vect.y / r;
454 
455                             vect.x = vect.x * new_r;
456                             vect.y = vect.y * new_r;
457                             v.z += cc.pLength(vect) * locLensEffect;
458                         }
459                     }
460                     this.setVertex(locPos, v);
461                 }
462             }
463             this._dirty = false;
464         }
465     }
466 });
467 
468 /**
469  * creates a lens 3d action with center position, radius
470  * @param {Number} duration
471  * @param {cc.Size} gridSize
472  * @param {cc.Point} position
473  * @param {Number} radius
474  * @return {cc.Lens3D}
475  */
476 cc.Lens3D.create = function (duration, gridSize, position, radius) {
477     return new cc.Lens3D(duration, gridSize, position, radius);
478 };
479 
480 /**
481  * cc.Ripple3D action
482  * @class
483  * @extends cc.Grid3DAction
484  */
485 cc.Ripple3D = cc.Grid3DAction.extend(/** @lends cc.Ripple3D# */{
486     /* center position */
487     _position: null,
488     _radius: 0,
489     _waves: 0,
490     _amplitude: 0,
491     _amplitudeRate: 0,
492 
493 	/**
494 	 * creates a ripple 3d action with radius, number of waves, amplitude
495 	 * Constructor of cc.Ripple3D
496 	 * @param {Number} duration
497 	 * @param {cc.Size} gridSize
498 	 * @param {cc.Point} position
499 	 * @param {Number} radius
500 	 * @param {Number} waves
501 	 * @param {Number} amplitude
502 	 */
503     ctor:function (duration, gridSize, position, radius, waves, amplitude) {
504         cc.GridAction.prototype.ctor.call(this);
505 
506         this._position = cc.p(0, 0);
507 		amplitude !== undefined && this.initWithDuration(duration, gridSize, position, radius, waves, amplitude);
508     },
509 
510     /**
511      * get center position
512      * @return {cc.Point}
513      */
514     getPosition:function () {
515         return this._position;
516     },
517 
518     /**
519      * set center position
520      * @param {cc.Point} position
521      */
522     setPosition:function (position) {
523         this._position.x = position.x;
524         this._position.y = position.y;
525     },
526 
527     /**
528      * get Amplitude
529      * @return {Number}
530      */
531     getAmplitude:function () {
532         return this._amplitude;
533     },
534 
535     /**
536      * set Amplitude
537      * @param {Number} amplitude
538      */
539     setAmplitude:function (amplitude) {
540         this._amplitude = amplitude;
541     },
542 
543     /**
544      * get Amplitude rate
545      * @return {*}
546      */
547     getAmplitudeRate:function () {
548         return this._amplitudeRate;
549     },
550 
551     /**
552      * get amplitude rate
553      * @param {Number} amplitudeRate
554      */
555     setAmplitudeRate:function (amplitudeRate) {
556         this._amplitudeRate = amplitudeRate;
557     },
558 
559     /**
560      * initializes the action with radius, number of waves, amplitude, a grid size and duration
561      * @param {Number} duration
562      * @param {cc.Size} gridSize
563      * @param {cc.Point} position
564      * @param {Number} radius
565      * @param {Number} waves
566      * @param {Number} amplitude
567      * @return {Boolean}
568      */
569     initWithDuration:function (duration, gridSize, position, radius, waves, amplitude) {
570         if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
571             this.setPosition(position);
572             this._radius = radius;
573             this._waves = waves;
574             this._amplitude = amplitude;
575             this._amplitudeRate = 1.0;
576             return true;
577         }
578         return false;
579     },
580 
581     update:function (time) {
582         var locGridSizeWidth = this._gridSize.width, locGridSizeHeight = this._gridSize.height;
583         var locPos = cc.p(0, 0), locRadius = this._radius;
584         var locWaves = this._waves, locAmplitude = this._amplitude, locAmplitudeRate = this._amplitudeRate;
585         var v, r, tempPos = cc.p(0, 0);
586         for (var i = 0; i < (locGridSizeWidth + 1); ++i) {
587             for (var j = 0; j < (locGridSizeHeight + 1); ++j) {
588                 locPos.x = i;
589                 locPos.y = j;
590                 v = this.originalVertex(locPos);
591 
592                 tempPos.x = this._position.x - v.x;
593                 tempPos.y = this._position.y - v.y;
594                 r = cc.pLength(tempPos);
595 
596                 if (r < locRadius) {
597                     r = locRadius - r;
598                     var rate = Math.pow(r / locRadius, 2);
599                     v.z += (Math.sin(time * Math.PI * locWaves * 2 + r * 0.1) * locAmplitude * locAmplitudeRate * rate);
600                 }
601                 this.setVertex(locPos, v);
602             }
603         }
604     }
605 });
606 
607 /**
608  * creates a ripple 3d action with radius, number of waves, amplitude
609  * @param {Number} duration
610  * @param {cc.Size} gridSize
611  * @param {cc.Point} position
612  * @param {Number} radius
613  * @param {Number} waves
614  * @param {Number} amplitude
615  * @return {cc.Ripple3D}
616  */
617 cc.Ripple3D.create = function (duration, gridSize, position, radius, waves, amplitude) {
618     return new cc.Ripple3D(duration, gridSize, position, radius, waves, amplitude);
619 };
620 
621 /**
622  * cc.Shaky3D action
623  * @class
624  * @extends cc.Grid3DAction
625  */
626 cc.Shaky3D = cc.Grid3DAction.extend(/** @lends cc.Shaky3D# */{
627     _randRange: 0,
628     _shakeZ: false,
629 
630 	/**
631 	 * Create a shaky3d action with a range, shake Z vertices
632 	 * Constructor of cc.Shaky3D
633 	 * @param {Number} duration
634 	 * @param {cc.Size} gridSize
635 	 * @param {Number} range
636 	 * @param {Boolean} shakeZ
637 	 */
638     ctor:function (duration, gridSize, range, shakeZ) {
639         cc.GridAction.prototype.ctor.call(this);
640 		shakeZ !== undefined && this.initWithDuration(duration, gridSize, range, shakeZ);
641     },
642 
643     /**
644      * initializes the action with a range, shake Z vertices, a grid and duration
645      * @param {Number} duration
646      * @param {cc.Size} gridSize
647      * @param {Number} range
648      * @param {Boolean} shakeZ
649      * @return {Boolean}
650      */
651     initWithDuration:function (duration, gridSize, range, shakeZ) {
652         if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
653             this._randRange = range;
654             this._shakeZ = shakeZ;
655             return true;
656         }
657         return false;
658     },
659 
660     update:function (time) {
661         var locGridSizeWidth = this._gridSize.width, locGridSizeHeight = this._gridSize.height;
662         var locRandRange = this._randRange, locShakeZ = this._shakeZ, locP = cc.p(0, 0);
663         var v;
664         for (var i = 0; i < (locGridSizeWidth + 1); ++i) {
665             for (var j = 0; j < (locGridSizeHeight + 1); ++j) {
666                 locP.x = i;
667                 locP.y = j;
668                 v = this.originalVertex(locP);
669                 v.x += (cc.rand() % (locRandRange * 2)) - locRandRange;
670                 v.y += (cc.rand() % (locRandRange * 2)) - locRandRange;
671                 if (locShakeZ)
672                     v.z += (cc.rand() % (locRandRange * 2)) - locRandRange;
673                 this.setVertex(locP, v);
674             }
675         }
676     }
677 });
678 
679 /**
680  * creates the action with a range, shake Z vertices, a grid and duration
681  * @param {Number} duration
682  * @param {cc.Size} gridSize
683  * @param {Number} range
684  * @param {Boolean} shakeZ
685  * @return {cc.Shaky3D}
686  */
687 cc.Shaky3D.create = function (duration, gridSize, range, shakeZ) {
688     return new cc.Shaky3D(duration, gridSize, range, shakeZ);
689 };
690 
691 /**
692  * cc.Liquid action
693  * @class
694  * @extends cc.Grid3DAction
695  */
696 cc.Liquid = cc.Grid3DAction.extend(/** @lends cc.Liquid# */{
697     _waves: 0,
698     _amplitude: 0,
699     _amplitudeRate: 0,
700 
701 	/**
702 	 * Create a liquid action with amplitude, a grid and duration
703 	 * Constructor of cc.Liquid
704 	 * @param {Number} duration
705 	 * @param {cc.Size} gridSize
706 	 * @param {Number} waves
707 	 * @param {Number} amplitude
708 	 */
709     ctor: function (duration, gridSize, waves, amplitude) {
710         cc.GridAction.prototype.ctor.call(this);
711 		amplitude !== undefined && this.initWithDuration(duration, gridSize, waves, amplitude);
712     },
713 
714     /**
715      * get amplitude
716      * @return {Number}
717      */
718     getAmplitude:function () {
719         return this._amplitude;
720     },
721 
722     /**
723      * set amplitude
724      * @param {Number} amplitude
725      */
726     setAmplitude:function (amplitude) {
727         this._amplitude = amplitude;
728     },
729 
730     /**
731      * get amplitude rate
732      * @return {Number}
733      */
734     getAmplitudeRate:function () {
735         return this._amplitudeRate;
736     },
737 
738     /**
739      * set amplitude rate
740      * @param {Number} amplitudeRate
741      */
742     setAmplitudeRate:function (amplitudeRate) {
743         this._amplitudeRate = amplitudeRate;
744     },
745 
746     /**
747      * initializes the action with amplitude, a grid and duration
748      * @param {Number} duration
749      * @param {cc.Size} gridSize
750      * @param {Number} waves
751      * @param {Number} amplitude
752      * @return {Boolean}
753      */
754     initWithDuration:function (duration, gridSize, waves, amplitude) {
755         if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
756             this._waves = waves;
757             this._amplitude = amplitude;
758             this._amplitudeRate = 1.0;
759             return true;
760         }
761         return false;
762     },
763 
764     update:function (time) {
765         var locSizeWidth = this._gridSize.width, locSizeHeight = this._gridSize.height, locPos = cc.p(0, 0);
766         var locWaves = this._waves, locAmplitude = this._amplitude, locAmplitudeRate = this._amplitudeRate;
767         var v;
768         for (var i = 1; i < locSizeWidth; ++i) {
769             for (var j = 1; j < locSizeHeight; ++j) {
770                 locPos.x = i;
771                 locPos.y = j;
772                 v = this.originalVertex(locPos);
773                 v.x = (v.x + (Math.sin(time * Math.PI * locWaves * 2 + v.x * .01) * locAmplitude * locAmplitudeRate));
774                 v.y = (v.y + (Math.sin(time * Math.PI * locWaves * 2 + v.y * .01) * locAmplitude * locAmplitudeRate));
775                 this.setVertex(locPos, v);
776             }
777         }
778     }
779 });
780 
781 /**
782  * creates the action with amplitude, a grid and duration
783  * @param {Number} duration
784  * @param {cc.Size} gridSize
785  * @param {Number} waves
786  * @param {Number} amplitude
787  * @return {cc.Liquid}
788  */
789 cc.Liquid.create = function (duration, gridSize, waves, amplitude) {
790     return new cc.Liquid(duration, gridSize, waves, amplitude);
791 };
792 
793 /**
794  * cc.Waves action
795  * @class
796  * @extends cc.Grid3DAction
797  */
798 cc.Waves = cc.Grid3DAction.extend(/** @lends cc.Waves# */{
799     _waves: 0,
800     _amplitude: 0,
801     _amplitudeRate: 0,
802     _vertical: false,
803     _horizontal: false,
804 
805 	/**
806 	 * Create a wave action with amplitude, horizontal sin, vertical sin, a grid and duration
807 	 * Constructor of cc.Waves
808 	 * @param {Number} duration
809 	 * @param {cc.Size} gridSize
810 	 * @param {Number} waves
811 	 * @param {Number} amplitude
812 	 * @param {Boolean} horizontal
813 	 * @param {Boolean} vertical
814 	 */
815     ctor: function (duration, gridSize, waves, amplitude, horizontal, vertical) {
816         cc.GridAction.prototype.ctor.call(this);
817 		vertical !== undefined && this.initWithDuration(duration, gridSize, waves, amplitude, horizontal, vertical);
818     },
819 
820     /**
821      * get amplitude
822      * @return {Number}
823      */
824     getAmplitude:function () {
825         return this._amplitude;
826     },
827 
828     /**
829      * set amplitude
830      * @param {Number} amplitude
831      */
832     setAmplitude:function (amplitude) {
833         this._amplitude = amplitude;
834     },
835 
836     /**
837      * get amplitude rate
838      * @return {Number}
839      */
840     getAmplitudeRate:function () {
841         return this._amplitudeRate;
842     },
843 
844     /**
845      * set amplitude rate
846      * @param {Number} amplitudeRate
847      */
848     setAmplitudeRate:function (amplitudeRate) {
849         this._amplitudeRate = amplitudeRate;
850     },
851 
852     /**
853      * initializes the action with amplitude, horizontal sin, vertical sin, a grid and duration
854      * @param {Number} duration
855      * @param {cc.Size} gridSize
856      * @param {Number} waves
857      * @param {Number} amplitude
858      * @param {Boolean} horizontal
859      * @param {Boolean} vertical
860      * @return {Boolean}
861      */
862     initWithDuration:function (duration, gridSize, waves, amplitude, horizontal, vertical) {
863         if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
864             this._waves = waves;
865             this._amplitude = amplitude;
866             this._amplitudeRate = 1.0;
867             this._horizontal = horizontal;
868             this._vertical = vertical;
869             return true;
870         }
871         return false;
872     },
873 
874     update:function (time) {
875         var locSizeWidth = this._gridSize.width, locSizeHeight = this._gridSize.height, locPos = cc.p(0, 0);
876         var locVertical = this._vertical, locHorizontal = this._horizontal;
877         var locWaves = this._waves, locAmplitude = this._amplitude, locAmplitudeRate = this._amplitudeRate;
878         var v;
879         for (var i = 0; i < locSizeWidth + 1; ++i) {
880             for (var j = 0; j < locSizeHeight + 1; ++j) {
881                 locPos.x = i;
882                 locPos.y = j;
883                 v = this.originalVertex(locPos);
884                 if (locVertical)
885                     v.x = (v.x + (Math.sin(time * Math.PI * locWaves * 2 + v.y * .01) * locAmplitude * locAmplitudeRate));
886                 if (locHorizontal)
887                     v.y = (v.y + (Math.sin(time * Math.PI * locWaves * 2 + v.x * .01) * locAmplitude * locAmplitudeRate));
888                 this.setVertex(locPos, v);
889             }
890         }
891     }
892 });
893 
894 /**
895  * initializes the action with amplitude, horizontal sin, vertical sin, a grid and duration
896  * @param {Number} duration
897  * @param {cc.Size} gridSize
898  * @param {Number} waves
899  * @param {Number} amplitude
900  * @param {Boolean} horizontal
901  * @param {Boolean} vertical
902  * @return {cc.Waves}
903  */
904 cc.Waves.create = function (duration, gridSize, waves, amplitude, horizontal, vertical) {
905     return new cc.Waves(duration, gridSize, waves, amplitude, horizontal, vertical);
906 };
907 
908 /** @brief  */
909 /**
910  * cc.Twirl action
911  * @class
912  * @extends cc.Grid3DAction
913  */
914 cc.Twirl = cc.Grid3DAction.extend(/** @lends cc.Twirl# */{
915     /* twirl center */
916     _position: null,
917     _twirls: 0,
918     _amplitude: 0,
919     _amplitudeRate: 0,
920 
921 	/**
922 	 * Create a grid 3d action with center position, number of twirls, amplitude, a grid size and duration
923 	 * Constructor of cc.Twirl
924 	 * @param {Number} duration
925 	 * @param {cc.Size} gridSize
926 	 * @param {cc.Point} position
927 	 * @param {Number} twirls
928 	 * @param {Number} amplitude
929 	 */
930     ctor:function (duration, gridSize, position, twirls, amplitude) {
931         cc.GridAction.prototype.ctor.call(this);
932 
933         this._position = cc.p(0, 0);
934 		amplitude !== undefined && this.initWithDuration(duration, gridSize, position, twirls, amplitude);
935     },
936 
937     /**
938      * get twirl center
939      * @return {cc.Point}
940      */
941     getPosition:function () {
942         return this._position;
943     },
944 
945     /**
946      * set twirl center
947      * @param {cc.Point} position
948      */
949     setPosition:function (position) {
950         this._position.x = position.x;
951         this._position.y = position.y;
952     },
953 
954     /**
955      * get amplitude
956      * @return {Number}
957      */
958     getAmplitude:function () {
959         return this._amplitude;
960     },
961 
962     /**
963      * set amplitude
964      * @param {Number} amplitude
965      */
966     setAmplitude:function (amplitude) {
967         this._amplitude = amplitude;
968     },
969 
970     /**
971      * get amplitude rate
972      * @return {Number}
973      */
974     getAmplitudeRate:function () {
975         return this._amplitudeRate;
976     },
977 
978     /**
979      * set amplitude rate
980      * @param {Number} amplitudeRate
981      */
982     setAmplitudeRate:function (amplitudeRate) {
983         this._amplitudeRate = amplitudeRate;
984     },
985 
986     /** initializes the action with center position, number of twirls, amplitude, a grid size and duration */
987     initWithDuration:function (duration, gridSize, position, twirls, amplitude) {
988         if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
989             this.setPosition(position);
990             this._twirls = twirls;
991             this._amplitude = amplitude;
992             this._amplitudeRate = 1.0;
993             return true;
994         }
995         return false;
996     },
997 
998     update:function (time) {
999         var c = this._position;
1000         var locSizeWidth = this._gridSize.width, locSizeHeight = this._gridSize.height, locPos = cc.p(0, 0);
1001         var amp = 0.1 * this._amplitude * this._amplitudeRate;
1002         var locTwirls = this._twirls;
1003         var v, a, dX, dY, avg = cc.p(0, 0);
1004         for (var i = 0; i < (locSizeWidth + 1); ++i) {
1005             for (var j = 0; j < (locSizeHeight + 1); ++j) {
1006                 locPos.x = i;
1007                 locPos.y = j;
1008                 v = this.originalVertex(locPos);
1009 
1010                 avg.x = i - (locSizeWidth / 2.0);
1011                 avg.y = j - (locSizeHeight / 2.0);
1012 
1013                 a = cc.pLength(avg) * Math.cos(Math.PI / 2.0 + time * Math.PI * locTwirls * 2) * amp;
1014 
1015                 dX = Math.sin(a) * (v.y - c.y) + Math.cos(a) * (v.x - c.x);
1016                 dY = Math.cos(a) * (v.y - c.y) - Math.sin(a) * (v.x - c.x);
1017 
1018                 v.x = c.x + dX;
1019                 v.y = c.y + dY;
1020 
1021                 this.setVertex(locPos, v);
1022             }
1023         }
1024     }
1025 });
1026 
1027 /**
1028  * creates the action with center position, number of twirls, amplitude, a grid size and duration
1029  * @param {Number} duration
1030  * @param {cc.Size} gridSize
1031  * @param {cc.Point} position
1032  * @param {Number} twirls
1033  * @param {Number} amplitude
1034  * @return {cc.Twirl}
1035  */
1036 cc.Twirl.create = function (duration, gridSize, position, twirls, amplitude) {
1037     return new cc.Twirl(duration, gridSize, position, twirls, amplitude);
1038 };
1039