CCActionGrid3D.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  1. /****************************************************************************
  2. Copyright (c) 2009 On-Core
  3. Copyright (c) 2010-2012 cocos2d-x.org
  4. Copyright (c) 2013-2017 Chukong Technologies Inc.
  5. http://www.cocos2d-x.org
  6. Permission is hereby granted, free of charge, to any person obtaining a copy
  7. of this software and associated documentation files (the "Software"), to deal
  8. in the Software without restriction, including without limitation the rights
  9. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. copies of the Software, and to permit persons to whom the Software is
  11. furnished to do so, subject to the following conditions:
  12. The above copyright notice and this permission notice shall be included in
  13. all copies or substantial portions of the Software.
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. THE SOFTWARE.
  21. ****************************************************************************/
  22. #include "2d/CCActionGrid3D.h"
  23. #include "base/CCDirector.h"
  24. NS_CC_BEGIN
  25. // implementation of Waves3D
  26. Waves3D* Waves3D::create(float duration, const Size& gridSize, unsigned int waves, float amplitude)
  27. {
  28. Waves3D *action = new (std::nothrow) Waves3D();
  29. if (action && action->initWithDuration(duration, gridSize, waves, amplitude))
  30. {
  31. action->autorelease();
  32. return action;
  33. }
  34. delete action;
  35. return nullptr;
  36. }
  37. bool Waves3D::initWithDuration(float duration, const Size& gridSize, unsigned int waves, float amplitude)
  38. {
  39. if (Grid3DAction::initWithDuration(duration, gridSize))
  40. {
  41. _waves = waves;
  42. _amplitude = amplitude;
  43. _amplitudeRate = 1.0f;
  44. return true;
  45. }
  46. return false;
  47. }
  48. Waves3D* Waves3D::clone() const
  49. {
  50. // no copy constructor
  51. return Waves3D::create(_duration, _gridSize, _waves, _amplitude);
  52. }
  53. void Waves3D::update(float time)
  54. {
  55. int i, j;
  56. for (i = 0; i < _gridSize.width + 1; ++i)
  57. {
  58. for (j = 0; j < _gridSize.height + 1; ++j)
  59. {
  60. Vec3 v = getOriginalVertex(Vec2(i ,j));
  61. v.z += (sinf((float)M_PI * time * _waves * 2 + (v.y+v.x) * 0.01f) * _amplitude * _amplitudeRate);
  62. //CCLOG("v.z offset is %f\n", (sinf((float)M_PI * time * _waves * 2 + (v.y+v.x) * .01f) * _amplitude * _amplitudeRate));
  63. setVertex(Vec2(i, j), v);
  64. }
  65. }
  66. }
  67. // implementation of FlipX3D
  68. FlipX3D* FlipX3D::create(float duration)
  69. {
  70. FlipX3D *action = new (std::nothrow) FlipX3D();
  71. if (action && action->initWithDuration(duration))
  72. {
  73. action->autorelease();
  74. return action;
  75. }
  76. delete action;
  77. return nullptr;
  78. }
  79. bool FlipX3D::initWithDuration(float duration)
  80. {
  81. return Grid3DAction::initWithDuration(duration, Size(1, 1));
  82. }
  83. bool FlipX3D::initWithSize(const Size& gridSize, float duration)
  84. {
  85. if (gridSize.width != 1 || gridSize.height != 1)
  86. {
  87. // Grid size must be (1,1)
  88. CCASSERT(0, "Grid size must be (1,1)");
  89. return false;
  90. }
  91. return Grid3DAction::initWithDuration(duration, gridSize);
  92. }
  93. FlipX3D* FlipX3D::clone() const
  94. {
  95. // no copy constructor
  96. auto a = new (std::nothrow) FlipX3D();
  97. a->initWithSize(_gridSize, _duration);
  98. a->autorelease();
  99. return a;
  100. }
  101. void FlipX3D::update(float time)
  102. {
  103. float angle = (float)M_PI * time; // 180 degrees
  104. float mz = sinf(angle);
  105. angle = angle / 2.0f; // x calculates degrees from 0 to 90
  106. float mx = cosf(angle);
  107. Vec3 v0, v1, v, diff;
  108. v0 = getOriginalVertex(Vec2(1.0f, 1.0f));
  109. v1 = getOriginalVertex(Vec2());
  110. float x0 = v0.x;
  111. float x1 = v1.x;
  112. float x;
  113. Vec2 a, b, c, d;
  114. if ( x0 > x1 )
  115. {
  116. // Normal Grid
  117. a.setZero();
  118. b.set(0.0f, 1.0f);
  119. c.set(1.0f, 0.0f);
  120. d.set(1.0f, 1.0f);
  121. x = x0;
  122. }
  123. else
  124. {
  125. // Reversed Grid
  126. c.setZero();
  127. d.set(0.0f, 1.0f);
  128. a.set(1.0f, 0.0f);
  129. b.set(1.0f, 1.0f);
  130. x = x1;
  131. }
  132. diff.x = ( x - x * mx );
  133. diff.z = fabsf( floorf( (x * mz) / 4.0f ) );
  134. // bottom-left
  135. v = getOriginalVertex(a);
  136. v.x = diff.x;
  137. v.z += diff.z;
  138. setVertex(a, v);
  139. // upper-left
  140. v = getOriginalVertex(b);
  141. v.x = diff.x;
  142. v.z += diff.z;
  143. setVertex(b, v);
  144. // bottom-right
  145. v = getOriginalVertex(c);
  146. v.x -= diff.x;
  147. v.z -= diff.z;
  148. setVertex(c, v);
  149. // upper-right
  150. v = getOriginalVertex(d);
  151. v.x -= diff.x;
  152. v.z -= diff.z;
  153. setVertex(d, v);
  154. }
  155. // implementation of FlipY3D
  156. FlipY3D* FlipY3D::clone() const
  157. {
  158. // no copy constructor
  159. auto a = new (std::nothrow) FlipY3D();
  160. a->initWithSize(_gridSize, _duration);
  161. a->autorelease();
  162. return a;
  163. }
  164. FlipY3D* FlipY3D::create(float duration)
  165. {
  166. FlipY3D *action = new (std::nothrow) FlipY3D();
  167. if (action)
  168. {
  169. if (action->initWithDuration(duration))
  170. {
  171. action->autorelease();
  172. }
  173. else
  174. {
  175. CC_SAFE_RELEASE_NULL(action);
  176. }
  177. }
  178. return action;
  179. }
  180. void FlipY3D::update(float time)
  181. {
  182. float angle = (float)M_PI * time; // 180 degrees
  183. float mz = sinf( angle );
  184. angle = angle / 2.0f; // x calculates degrees from 0 to 90
  185. float my = cosf(angle);
  186. Vec3 v0, v1, v, diff;
  187. v0 = getOriginalVertex(Vec2(1.0f, 1.0f));
  188. v1 = getOriginalVertex(Vec2());
  189. float y0 = v0.y;
  190. float y1 = v1.y;
  191. float y;
  192. Vec2 a, b, c, d;
  193. if (y0 > y1)
  194. {
  195. // Normal Grid
  196. a.setZero();
  197. b.set(0.0f, 1.0f);
  198. c.set(1.0f, 0.0f);
  199. d.set(1.0f, 1.0f);
  200. y = y0;
  201. }
  202. else
  203. {
  204. // Reversed Grid
  205. b.setZero();
  206. a.set(0.0f, 1.0f);
  207. d.set(1.0f, 0.0f);
  208. c.set(1.0f, 1.0f);
  209. y = y1;
  210. }
  211. diff.y = y - y * my;
  212. diff.z = fabsf(floorf((y * mz) / 4.0f));
  213. // bottom-left
  214. v = getOriginalVertex(a);
  215. v.y = diff.y;
  216. v.z += diff.z;
  217. setVertex(a, v);
  218. // upper-left
  219. v = getOriginalVertex(b);
  220. v.y -= diff.y;
  221. v.z -= diff.z;
  222. setVertex(b, v);
  223. // bottom-right
  224. v = getOriginalVertex(c);
  225. v.y = diff.y;
  226. v.z += diff.z;
  227. setVertex(c, v);
  228. // upper-right
  229. v = getOriginalVertex(d);
  230. v.y -= diff.y;
  231. v.z -= diff.z;
  232. setVertex(d, v);
  233. }
  234. // implementation of Lens3D
  235. Lens3D* Lens3D::create(float duration, const Size& gridSize, const Vec2& position, float radius)
  236. {
  237. Lens3D *action = new (std::nothrow) Lens3D();
  238. if (action)
  239. {
  240. if (action->initWithDuration(duration, gridSize, position, radius))
  241. {
  242. action->autorelease();
  243. }
  244. else
  245. {
  246. CC_SAFE_RELEASE_NULL(action);
  247. }
  248. }
  249. return action;
  250. }
  251. bool Lens3D::initWithDuration(float duration, const Size& gridSize, const Vec2& position, float radius)
  252. {
  253. if (Grid3DAction::initWithDuration(duration, gridSize))
  254. {
  255. _position.set(-1.0f, -1.0f);
  256. setPosition(position);
  257. _radius = radius;
  258. _lensEffect = 0.7f;
  259. _concave = false;
  260. _dirty = true;
  261. return true;
  262. }
  263. return false;
  264. }
  265. Lens3D* Lens3D::clone() const
  266. {
  267. // no copy constructor
  268. auto a = new (std::nothrow) Lens3D();
  269. a->initWithDuration(_duration, _gridSize, _position, _radius);
  270. a->autorelease();
  271. return a;
  272. }
  273. void Lens3D::setPosition(const Vec2& pos)
  274. {
  275. if( !pos.equals(_position))
  276. {
  277. _position = pos;
  278. _dirty = true;
  279. }
  280. }
  281. void Lens3D::update(float /*time*/)
  282. {
  283. if (_dirty)
  284. {
  285. int i, j;
  286. for (i = 0; i < _gridSize.width + 1; ++i)
  287. {
  288. for (j = 0; j < _gridSize.height + 1; ++j)
  289. {
  290. Vec3 v = getOriginalVertex(Vec2(i, j));
  291. Vec2 vect = _position - Vec2(v.x, v.y);
  292. float r = vect.getLength();
  293. if (r < _radius)
  294. {
  295. r = _radius - r;
  296. float pre_log = r / _radius;
  297. if ( pre_log == 0 )
  298. {
  299. pre_log = 0.001f;
  300. }
  301. float l = logf(pre_log) * _lensEffect;
  302. float new_r = expf( l ) * _radius;
  303. if (vect.getLength() > 0)
  304. {
  305. vect.normalize();
  306. Vec2 new_vect = vect * new_r;
  307. v.z += (_concave ? -1.0f : 1.0f) * new_vect.getLength() * _lensEffect;
  308. }
  309. }
  310. setVertex(Vec2(i, j), v);
  311. }
  312. }
  313. _dirty = false;
  314. }
  315. }
  316. // implementation of Ripple3D
  317. Ripple3D* Ripple3D::create(float duration, const Size& gridSize, const Vec2& position, float radius, unsigned int waves, float amplitude)
  318. {
  319. Ripple3D *action = new (std::nothrow) Ripple3D();
  320. if (action)
  321. {
  322. if (action->initWithDuration(duration, gridSize, position, radius, waves, amplitude))
  323. {
  324. action->autorelease();
  325. }
  326. else
  327. {
  328. CC_SAFE_RELEASE_NULL(action);
  329. }
  330. }
  331. return action;
  332. }
  333. bool Ripple3D::initWithDuration(float duration, const Size& gridSize, const Vec2& position, float radius, unsigned int waves, float amplitude)
  334. {
  335. if (Grid3DAction::initWithDuration(duration, gridSize))
  336. {
  337. setPosition(position);
  338. _radius = radius;
  339. _waves = waves;
  340. _amplitude = amplitude;
  341. _amplitudeRate = 1.0f;
  342. return true;
  343. }
  344. return false;
  345. }
  346. void Ripple3D::setPosition(const Vec2& position)
  347. {
  348. _position = position;
  349. }
  350. Ripple3D* Ripple3D::clone() const
  351. {
  352. // no copy constructor
  353. auto a = new (std::nothrow) Ripple3D();
  354. a->initWithDuration(_duration, _gridSize, _position, _radius, _waves, _amplitude);
  355. a->autorelease();
  356. return a;
  357. }
  358. void Ripple3D::update(float time)
  359. {
  360. int i, j;
  361. for (i = 0; i < (_gridSize.width+1); ++i)
  362. {
  363. for (j = 0; j < (_gridSize.height+1); ++j)
  364. {
  365. Vec3 v = getOriginalVertex(Vec2(i, j));
  366. Vec2 vect = _position - Vec2(v.x,v.y);
  367. float r = vect.getLength();
  368. if (r < _radius)
  369. {
  370. r = _radius - r;
  371. float rate = powf(r / _radius, 2);
  372. v.z += (sinf( time*(float)M_PI * _waves * 2 + r * 0.1f) * _amplitude * _amplitudeRate * rate);
  373. }
  374. setVertex(Vec2(i, j), v);
  375. }
  376. }
  377. }
  378. // implementation of Shaky3D
  379. Shaky3D* Shaky3D::create(float duration, const Size& gridSize, int range, bool shakeZ)
  380. {
  381. Shaky3D *action = new (std::nothrow) Shaky3D();
  382. if (action)
  383. {
  384. if (action->initWithDuration(duration, gridSize, range, shakeZ))
  385. {
  386. action->autorelease();
  387. }
  388. else
  389. {
  390. CC_SAFE_RELEASE_NULL(action);
  391. }
  392. }
  393. return action;
  394. }
  395. bool Shaky3D::initWithDuration(float duration, const Size& gridSize, int range, bool shakeZ)
  396. {
  397. if (Grid3DAction::initWithDuration(duration, gridSize))
  398. {
  399. _randrange = range;
  400. _shakeZ = shakeZ;
  401. return true;
  402. }
  403. return false;
  404. }
  405. Shaky3D* Shaky3D::clone() const
  406. {
  407. // no copy constructor
  408. auto a = new (std::nothrow) Shaky3D();
  409. a->initWithDuration(_duration, _gridSize, _randrange, _shakeZ);
  410. a->autorelease();
  411. return a;
  412. }
  413. void Shaky3D::update(float /*time*/)
  414. {
  415. int i, j;
  416. for (i = 0; i < (_gridSize.width+1); ++i)
  417. {
  418. for (j = 0; j < (_gridSize.height+1); ++j)
  419. {
  420. Vec3 v = getOriginalVertex(Vec2(i ,j));
  421. v.x += (rand() % (_randrange*2)) - _randrange;
  422. v.y += (rand() % (_randrange*2)) - _randrange;
  423. if (_shakeZ)
  424. {
  425. v.z += (rand() % (_randrange*2)) - _randrange;
  426. }
  427. setVertex(Vec2(i, j), v);
  428. }
  429. }
  430. }
  431. // implementation of Liquid
  432. Liquid* Liquid::create(float duration, const Size& gridSize, unsigned int waves, float amplitude)
  433. {
  434. Liquid *action = new (std::nothrow) Liquid();
  435. if (action)
  436. {
  437. if (action->initWithDuration(duration, gridSize, waves, amplitude))
  438. {
  439. action->autorelease();
  440. }
  441. else
  442. {
  443. CC_SAFE_RELEASE_NULL(action);
  444. }
  445. }
  446. return action;
  447. }
  448. bool Liquid::initWithDuration(float duration, const Size& gridSize, unsigned int waves, float amplitude)
  449. {
  450. if (Grid3DAction::initWithDuration(duration, gridSize))
  451. {
  452. _waves = waves;
  453. _amplitude = amplitude;
  454. _amplitudeRate = 1.0f;
  455. return true;
  456. }
  457. return false;
  458. }
  459. Liquid* Liquid::clone() const
  460. {
  461. // no copy constructor
  462. auto a = new (std::nothrow) Liquid();
  463. a->initWithDuration(_duration, _gridSize, _waves, _amplitude);
  464. a->autorelease();
  465. return a;
  466. }
  467. void Liquid::update(float time)
  468. {
  469. int i, j;
  470. for (i = 1; i < _gridSize.width; ++i)
  471. {
  472. for (j = 1; j < _gridSize.height; ++j)
  473. {
  474. Vec3 v = getOriginalVertex(Vec2(i, j));
  475. v.x = (v.x + (sinf(time * (float)M_PI * _waves * 2 + v.x * .01f) * _amplitude * _amplitudeRate));
  476. v.y = (v.y + (sinf(time * (float)M_PI * _waves * 2 + v.y * .01f) * _amplitude * _amplitudeRate));
  477. setVertex(Vec2(i, j), v);
  478. }
  479. }
  480. }
  481. // implementation of Waves
  482. Waves* Waves::create(float duration, const Size& gridSize, unsigned int waves, float amplitude, bool horizontal, bool vertical)
  483. {
  484. Waves *action = new (std::nothrow) Waves();
  485. if (action)
  486. {
  487. if (action->initWithDuration(duration, gridSize, waves, amplitude, horizontal, vertical))
  488. {
  489. action->autorelease();
  490. }
  491. else
  492. {
  493. CC_SAFE_RELEASE_NULL(action);
  494. }
  495. }
  496. return action;
  497. }
  498. bool Waves::initWithDuration(float duration, const Size& gridSize, unsigned int waves, float amplitude, bool horizontal, bool vertical)
  499. {
  500. if (Grid3DAction::initWithDuration(duration, gridSize))
  501. {
  502. _waves = waves;
  503. _amplitude = amplitude;
  504. _amplitudeRate = 1.0f;
  505. _horizontal = horizontal;
  506. _vertical = vertical;
  507. return true;
  508. }
  509. return false;
  510. }
  511. Waves* Waves::clone() const
  512. {
  513. // no copy constructor
  514. auto a = new (std::nothrow) Waves();
  515. a->initWithDuration(_duration, _gridSize, _waves, _amplitude, _horizontal, _vertical);
  516. a->autorelease();
  517. return a;
  518. }
  519. void Waves::update(float time)
  520. {
  521. int i, j;
  522. for (i = 0; i < _gridSize.width + 1; ++i)
  523. {
  524. for (j = 0; j < _gridSize.height + 1; ++j)
  525. {
  526. Vec3 v = getOriginalVertex(Vec2(i, j));
  527. if (_vertical)
  528. {
  529. v.x = (v.x + (sinf(time * (float)M_PI * _waves * 2 + v.y * .01f) * _amplitude * _amplitudeRate));
  530. }
  531. if (_horizontal)
  532. {
  533. v.y = (v.y + (sinf(time * (float)M_PI * _waves * 2 + v.x * .01f) * _amplitude * _amplitudeRate));
  534. }
  535. setVertex(Vec2(i, j), v);
  536. }
  537. }
  538. }
  539. // implementation of Twirl
  540. Twirl* Twirl::create(float duration, const Size& gridSize, const Vec2& position, unsigned int twirls, float amplitude)
  541. {
  542. Twirl *action = new (std::nothrow) Twirl();
  543. if (action)
  544. {
  545. if (action->initWithDuration(duration, gridSize, position, twirls, amplitude))
  546. {
  547. action->autorelease();
  548. }
  549. else
  550. {
  551. CC_SAFE_RELEASE_NULL(action);
  552. }
  553. }
  554. return action;
  555. }
  556. bool Twirl::initWithDuration(float duration, const Size& gridSize, const Vec2& position, unsigned int twirls, float amplitude)
  557. {
  558. if (Grid3DAction::initWithDuration(duration, gridSize))
  559. {
  560. setPosition(position);
  561. _twirls = twirls;
  562. _amplitude = amplitude;
  563. _amplitudeRate = 1.0f;
  564. return true;
  565. }
  566. return false;
  567. }
  568. void Twirl::setPosition(const Vec2& position)
  569. {
  570. _position = position;
  571. }
  572. Twirl *Twirl::clone() const
  573. {
  574. // no copy constructor
  575. auto a = new (std::nothrow) Twirl();
  576. a->initWithDuration(_duration, _gridSize, _position, _twirls, _amplitude);
  577. a->autorelease();
  578. return a;
  579. }
  580. void Twirl::update(float time)
  581. {
  582. int i, j;
  583. Vec2 c = _position;
  584. for (i = 0; i < (_gridSize.width+1); ++i)
  585. {
  586. for (j = 0; j < (_gridSize.height+1); ++j)
  587. {
  588. Vec3 v = getOriginalVertex(Vec2(i ,j));
  589. Vec2 avg(i-(_gridSize.width/2.0f), j-(_gridSize.height/2.0f));
  590. float r = avg.getLength();
  591. float amp = 0.1f * _amplitude * _amplitudeRate;
  592. float a = r * cosf( (float)M_PI/2.0f + time * (float)M_PI * _twirls * 2 ) * amp;
  593. Vec2 d(
  594. sinf(a) * (v.y-c.y) + cosf(a) * (v.x-c.x),
  595. cosf(a) * (v.y-c.y) - sinf(a) * (v.x-c.x));
  596. v.x = c.x + d.x;
  597. v.y = c.y + d.y;
  598. setVertex(Vec2(i ,j), v);
  599. }
  600. }
  601. }
  602. NS_CC_END