CCPUEmitter.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969
  1. /****************************************************************************
  2. Copyright (C) 2013 Henry van Merode. All rights reserved.
  3. Copyright (c) 2015-2017 Chukong Technologies Inc.
  4. http://www.cocos2d-x.org
  5. Permission is hereby granted, free of charge, to any person obtaining a copy
  6. of this software and associated documentation files (the "Software"), to deal
  7. in the Software without restriction, including without limitation the rights
  8. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. copies of the Software, and to permit persons to whom the Software is
  10. furnished to do so, subject to the following conditions:
  11. The above copyright notice and this permission notice shall be included in
  12. all copies or substantial portions of the Software.
  13. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. THE SOFTWARE.
  20. ****************************************************************************/
  21. #include "CCPUEmitter.h"
  22. #include "extensions/Particle3D/PU/CCPUParticleSystem3D.h"
  23. #include "extensions/Particle3D/PU/CCPUUtil.h"
  24. NS_CC_BEGIN
  25. // Constants
  26. const bool PUEmitter::DEFAULT_ENABLED = true;
  27. const Vec3 PUEmitter::DEFAULT_POSITION(0, 0, 0);
  28. const bool PUEmitter::DEFAULT_KEEP_LOCAL = false;
  29. const Vec3 PUEmitter::DEFAULT_DIRECTION(0, 1, 0);
  30. const Quaternion PUEmitter::DEFAULT_ORIENTATION(1, 0, 0, 0);
  31. const Quaternion PUEmitter::DEFAULT_ORIENTATION_RANGE_START(1, 0, 0, 0);
  32. const Quaternion PUEmitter::DEFAULT_ORIENTATION_RANGE_END(1, 0, 0, 0);
  33. //const Particle::ParticleType PUEmitter::DEFAULT_EMITS = VisualParticle::PT_VISUAL;
  34. const unsigned short PUEmitter::DEFAULT_START_TEXTURE_COORDS = 0;
  35. const unsigned short PUEmitter::DEFAULT_END_TEXTURE_COORDS = 0;
  36. const unsigned short PUEmitter::DEFAULT_TEXTURE_COORDS = 0;
  37. const Vec4 PUEmitter::DEFAULT_START_COLOUR_RANGE(0, 0, 0, 1);
  38. const Vec4 PUEmitter::DEFAULT_END_COLOUR_RANGE(1, 1, 1, 1);
  39. const Vec4 PUEmitter::DEFAULT_COLOUR(1, 1, 1, 1);
  40. const bool PUEmitter::DEFAULT_AUTO_DIRECTION = false;
  41. const bool PUEmitter::DEFAULT_FORCE_EMISSION = false;
  42. const float PUEmitter::DEFAULT_EMISSION_RATE = 10.0f;
  43. const float PUEmitter::DEFAULT_TIME_TO_LIVE = 3.0f;
  44. const float PUEmitter::DEFAULT_MASS = 1.0f;
  45. const float PUEmitter::DEFAULT_VELOCITY = 100.0f;
  46. const float PUEmitter::DEFAULT_DURATION = 0.0f;
  47. const float PUEmitter::DEFAULT_REPEAT_DELAY = 0.0f;
  48. const float PUEmitter::DEFAULT_ANGLE = 20.0f;
  49. const float PUEmitter::DEFAULT_DIMENSIONS = 0.0f;
  50. const float PUEmitter::DEFAULT_WIDTH = 0.0f;
  51. const float PUEmitter::DEFAULT_HEIGHT = 0.0f;
  52. const float PUEmitter::DEFAULT_DEPTH = 0.0f;
  53. PUEmitter::PUEmitter()
  54. : //mEmitsType(DEFAULT_EMITS),
  55. //mEmitsName(StringUtil::BLANK),
  56. _emitterScale(Vec3::ONE),
  57. _particleDirection(DEFAULT_DIRECTION),
  58. _originalParticleDirection(DEFAULT_DIRECTION),
  59. //mParticleOrientation(Quaternion::IDENTITY),
  60. //mParticleOrientationRangeStart(Quaternion::IDENTITY),
  61. //mParticleOrientationRangeEnd(Quaternion::IDENTITY),
  62. _particleOrientationRangeSet(false),
  63. _dynParticleAllDimensionsSet(false),
  64. _dynParticleWidthSet(false),
  65. _dynParticleHeightSet(false),
  66. _dynParticleDepthSet(false),
  67. _remainder(0),
  68. _durationRemain(0),
  69. _dynDurationSet(false),
  70. _repeatDelayRemain(0),
  71. _dynRepeatDelaySet(false),
  72. _autoDirection(DEFAULT_AUTO_DIRECTION),
  73. _forceEmission(DEFAULT_FORCE_EMISSION),
  74. _originalForceEmission(false),
  75. _forceEmissionExecuted(false),
  76. _originalForceEmissionExecuted(false),
  77. //mName(StringUtil::BLANK),
  78. _particleColor(DEFAULT_COLOUR),
  79. _particleColorRangeStart(DEFAULT_START_COLOUR_RANGE),
  80. _particleColorRangeEnd(DEFAULT_END_COLOUR_RANGE),
  81. _particleColorRangeSet(false),
  82. _keepLocal(false),
  83. _particleTextureCoords(DEFAULT_TEXTURE_COORDS),
  84. _particleTextureCoordsRangeStart(DEFAULT_START_TEXTURE_COORDS),
  85. _particleTextureCoordsRangeEnd(DEFAULT_END_TEXTURE_COORDS),
  86. _particleTextureCoordsRangeSet(false),
  87. _originEnabled(true),
  88. _originEnabledSet(false),
  89. _emitsType(PUParticle3D::PT_VISUAL),
  90. _emitsEntity(nullptr),
  91. _isMarkedForEmission(false)
  92. {
  93. //particleType = PT_EMITTER;
  94. //mAliasType = AT_EMITTER;
  95. _dynEmissionRate = new (std::nothrow) PUDynamicAttributeFixed();
  96. (static_cast<PUDynamicAttributeFixed*>(_dynEmissionRate))->setValue(DEFAULT_EMISSION_RATE);
  97. _dynTotalTimeToLive = new (std::nothrow) PUDynamicAttributeFixed();
  98. (static_cast<PUDynamicAttributeFixed*>(_dynTotalTimeToLive))->setValue(DEFAULT_TIME_TO_LIVE);
  99. _dynParticleMass = new (std::nothrow) PUDynamicAttributeFixed();
  100. (static_cast<PUDynamicAttributeFixed*>(_dynParticleMass))->setValue(DEFAULT_MASS);
  101. _dynVelocity = new (std::nothrow) PUDynamicAttributeFixed();
  102. (static_cast<PUDynamicAttributeFixed*>(_dynVelocity))->setValue(DEFAULT_VELOCITY);
  103. _dynDuration = new (std::nothrow) PUDynamicAttributeFixed();
  104. (static_cast<PUDynamicAttributeFixed*>(_dynDuration))->setValue(DEFAULT_DURATION);
  105. _dynRepeatDelay = new (std::nothrow) PUDynamicAttributeFixed();
  106. (static_cast<PUDynamicAttributeFixed*>(_dynRepeatDelay))->setValue(DEFAULT_REPEAT_DELAY);
  107. _dynAngle = new (std::nothrow) PUDynamicAttributeFixed();
  108. (static_cast<PUDynamicAttributeFixed*>(_dynAngle))->setValue(DEFAULT_ANGLE);
  109. // Set the dimensions attributes to 0; the default is to use the default dimensions of the ParticleTechnique
  110. _dynParticleAllDimensions = new (std::nothrow) PUDynamicAttributeFixed();
  111. (static_cast<PUDynamicAttributeFixed*>(_dynParticleAllDimensions))->setValue(DEFAULT_DIMENSIONS);
  112. _dynParticleWidth = new (std::nothrow) PUDynamicAttributeFixed();
  113. (static_cast<PUDynamicAttributeFixed*>(_dynParticleWidth))->setValue(DEFAULT_WIDTH);
  114. _dynParticleHeight = new (std::nothrow) PUDynamicAttributeFixed();
  115. (static_cast<PUDynamicAttributeFixed*>(_dynParticleHeight))->setValue(DEFAULT_HEIGHT);
  116. _dynParticleDepth = new (std::nothrow) PUDynamicAttributeFixed();
  117. (static_cast<PUDynamicAttributeFixed*>(_dynParticleDepth))->setValue(DEFAULT_DEPTH);
  118. }
  119. PUEmitter::~PUEmitter()
  120. {
  121. _particleSystem = nullptr;
  122. if (_dynEmissionRate)
  123. delete _dynEmissionRate;
  124. if (_dynTotalTimeToLive)
  125. delete _dynTotalTimeToLive;
  126. if (_dynParticleMass)
  127. delete _dynParticleMass;
  128. if (_dynVelocity)
  129. delete _dynVelocity;
  130. if (_dynDuration)
  131. delete _dynDuration;
  132. if (_dynRepeatDelay)
  133. delete _dynRepeatDelay;
  134. if (_dynParticleAllDimensions)
  135. delete _dynParticleAllDimensions;
  136. if (_dynParticleWidth)
  137. delete _dynParticleWidth;
  138. if (_dynParticleHeight)
  139. delete _dynParticleHeight;
  140. if (_dynParticleDepth)
  141. delete _dynParticleDepth;
  142. //if (mEmissionRateCameraDependency)
  143. // mCameraDependencyFactory.destroy(mEmissionRateCameraDependency);
  144. if (_dynAngle)
  145. delete _dynAngle;
  146. }
  147. void PUEmitter::updateEmitter(Particle3D* /*particle*/, float /*deltaTime*/)
  148. {
  149. }
  150. void PUEmitter::emit(int /*count*/)
  151. {
  152. }
  153. void PUEmitter::initParticlePosition( PUParticle3D* particle )
  154. {
  155. particle->position = getDerivedPosition();
  156. particle->originalPosition = particle->position;
  157. particle->latestPosition = particle->position;
  158. }
  159. const Vec3& PUEmitter::getDerivedPosition()
  160. {
  161. if (_isMarkedForEmission){
  162. _derivedPosition = _position;
  163. }else {
  164. PUParticleSystem3D *ps = static_cast<PUParticleSystem3D *>(_particleSystem);
  165. Mat4 rotMat;
  166. Mat4::createRotation(ps->getDerivedOrientation(), &rotMat);
  167. _derivedPosition = ps->getDerivedPosition() + rotMat * Vec3(_position.x * _emitterScale.x, _position.y * _emitterScale.y, _position.z * _emitterScale.z);
  168. //_particleSystem->getNodeToWorldTransform().transformPoint(_position, &_derivedPosition);
  169. }
  170. return _derivedPosition;
  171. }
  172. void PUEmitter::initParticleOrientation( PUParticle3D* particle )
  173. {
  174. if (_particleOrientationRangeSet)
  175. {
  176. // Generate random orientation 'between' start en end.
  177. Quaternion::lerp(_particleOrientationRangeStart, _particleOrientationRangeEnd, CCRANDOM_0_1(), &particle->orientation);
  178. }
  179. else
  180. {
  181. particle->orientation = _particleOrientation;
  182. }
  183. // Set original orientation
  184. particle->originalOrientation = particle->orientation;
  185. }
  186. void PUEmitter::initParticleDirection( PUParticle3D* particle )
  187. {
  188. // Use the default way of initialising the particle direction
  189. float angle = 0.0f;
  190. generateAngle(angle);
  191. if (angle != 0.0f)
  192. {
  193. particle->direction = PUUtil::randomDeviant(_particleDirection, angle, _upVector);
  194. }
  195. else
  196. {
  197. particle->direction = _particleDirection;
  198. }
  199. particle->originalDirection = particle->direction;
  200. particle->originalDirectionLength = particle->direction.length();
  201. }
  202. void PUEmitter::generateAngle( float &angle )
  203. {
  204. float a = CC_DEGREES_TO_RADIANS(_dynamicAttributeHelper.calculate(_dynAngle, (static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart()));
  205. angle = a;
  206. if (_dynAngle->getType() == PUDynamicAttribute::DAT_FIXED)
  207. {
  208. // Make an exception here and don't use the fixed angle.
  209. angle = CCRANDOM_0_1() * angle;
  210. }
  211. }
  212. unsigned short PUEmitter::calculateRequestedParticles( float timeElapsed )
  213. {
  214. unsigned short requestedParticles = 0;
  215. //FIXME
  216. if (_isEnabled)
  217. {
  218. if (_dynEmissionRate)
  219. {
  220. float rate = _dynEmissionRate->getValue((static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart());
  221. //if (_emissionRateCameraDependency)
  222. //{
  223. // // Affect the emission rate based on the camera distance
  224. // mEmissionRateCameraDependency->affect(rate, mParentTechnique->getCameraSquareDistance());
  225. //}
  226. if (_forceEmission)
  227. {
  228. if (_forceEmissionExecuted)
  229. {
  230. // It is a single-shot system, so there is nothing left anymore.
  231. requestedParticles = 0;
  232. }
  233. else
  234. {
  235. // Ignore the time. Just emit everything at once (if you absolutely need it).
  236. // The emitter cannot be disabled yet, because it needs to emit its particles first.
  237. requestedParticles = (unsigned short)rate;
  238. _forceEmissionExecuted = true;
  239. }
  240. }
  241. else
  242. {
  243. // Particle emission is time driven
  244. _remainder += rate * timeElapsed;
  245. requestedParticles = (unsigned short)_remainder;
  246. }
  247. _remainder -= requestedParticles;
  248. }
  249. // Determine whether the duration period has been exceeded.
  250. if (_dynDurationSet)
  251. {
  252. _durationRemain -= timeElapsed;
  253. if (_durationRemain <= 0)
  254. {
  255. setEnabled(false);
  256. }
  257. }
  258. }
  259. else if (_dynRepeatDelaySet)
  260. {
  261. _repeatDelayRemain -= timeElapsed;
  262. if (_repeatDelayRemain <= 0)
  263. {
  264. //// Initialise again (if stopfade isn't set)
  265. //if (mParentTechnique)
  266. //{
  267. // if (!mParentTechnique->isStopFade())
  268. // {
  269. // setEnabled(true);
  270. // }
  271. //}
  272. //else
  273. //{
  274. // setEnabled(true);
  275. //}
  276. setEnabled(true);
  277. }
  278. }
  279. return requestedParticles;
  280. }
  281. void PUEmitter::setEnabled( bool enabled )
  282. {
  283. _isEnabled = enabled;
  284. if (!_originEnabledSet){
  285. _originEnabled = enabled;
  286. _originEnabledSet = true;
  287. }
  288. initTimeBased();
  289. }
  290. bool PUEmitter::isEnabled( void ) const
  291. {
  292. return _isEnabled;
  293. }
  294. void PUEmitter::notifyStart()
  295. {
  296. _forceEmission = _originalForceEmission;
  297. _forceEmissionExecuted = _originalForceEmissionExecuted;
  298. _remainder = 0;
  299. _durationRemain = 0;
  300. _repeatDelayRemain = 0;
  301. setEnabled(_originEnabled); // Also calls _initTimeBased
  302. }
  303. void PUEmitter::notifyRescaled( const Vec3& scale )
  304. {
  305. _emitterScale = scale;
  306. }
  307. void PUEmitter::notifyStop()
  308. {
  309. }
  310. void PUEmitter::notifyPause()
  311. {
  312. }
  313. void PUEmitter::notifyResume()
  314. {
  315. }
  316. void PUEmitter::prepare()
  317. {
  318. if (!_emitsEntity){
  319. if (_emitsType == PUParticle3D::PT_EMITTER){
  320. auto emitter = static_cast<PUParticleSystem3D *>(_particleSystem)->getEmitter(_emitsName);
  321. if (emitter){
  322. emitter->setMarkedForEmission(true);
  323. _emitsEntity = emitter;
  324. }
  325. }
  326. else if (_emitsType == PUParticle3D::PT_TECHNIQUE){
  327. PUParticleSystem3D *system = static_cast<PUParticleSystem3D *>(_particleSystem)->getParentParticleSystem();
  328. if (system){
  329. auto children = system->getChildren();
  330. for (auto it : children){
  331. if (it->getName() == _emitsName)
  332. {
  333. static_cast<PUParticleSystem3D *>(it)->setMarkedForEmission(true);
  334. _emitsEntity = it;
  335. break;
  336. }
  337. }
  338. }
  339. }
  340. }
  341. _latestPosition = getDerivedPosition(); // V1.3.1
  342. }
  343. void PUEmitter::unPrepare()
  344. {
  345. setForceEmission(_forceEmission);
  346. }
  347. void PUEmitter::preUpdateEmitter( float /*deltaTime*/ )
  348. {
  349. }
  350. void PUEmitter::postUpdateEmitter( float /*deltaTime*/ )
  351. {
  352. Vec3 currentPos = getDerivedPosition();
  353. _latestPositionDiff = currentPos - _latestPosition;
  354. _latestPosition = currentPos;
  355. }
  356. //-----------------------------------------------------------------------
  357. bool PUEmitter::isKeepLocal(void) const
  358. {
  359. return _keepLocal;
  360. }
  361. //-----------------------------------------------------------------------
  362. void PUEmitter::setKeepLocal(bool keepLocal)
  363. {
  364. _keepLocal = keepLocal;
  365. }
  366. //-----------------------------------------------------------------------
  367. bool PUEmitter::makeParticleLocal(PUParticle3D* particle)
  368. {
  369. if (!particle)
  370. return true;
  371. if (!_keepLocal/* || hasEventFlags(PUParticle3D::PEF_EXPIRED)*/)
  372. return false;
  373. particle->position += _latestPositionDiff;
  374. return true;
  375. }
  376. //-----------------------------------------------------------------------
  377. const Vec4& PUEmitter::getParticleColor(void) const
  378. {
  379. return _particleColor;
  380. }
  381. //-----------------------------------------------------------------------
  382. void PUEmitter::setParticleColor(const Vec4& particleColor)
  383. {
  384. _particleColor = particleColor;
  385. }
  386. //-----------------------------------------------------------------------
  387. const Vec4& PUEmitter::getParticleColorRangeStart(void) const
  388. {
  389. return _particleColorRangeStart;
  390. }
  391. //-----------------------------------------------------------------------
  392. void PUEmitter::setParticleColorRangeStart(const Vec4& particleColorRangeStart)
  393. {
  394. _particleColorRangeStart = particleColorRangeStart;
  395. _particleColorRangeSet = true;
  396. }
  397. //-----------------------------------------------------------------------
  398. const Vec4& PUEmitter::getParticleColorRangeEnd(void) const
  399. {
  400. return _particleColorRangeEnd;
  401. }
  402. //-----------------------------------------------------------------------
  403. void PUEmitter::setParticleColorRangeEnd(const Vec4& particleColorRangeEnd)
  404. {
  405. _particleColorRangeEnd = particleColorRangeEnd;
  406. _particleColorRangeSet = true;
  407. }
  408. //-----------------------------------------------------------------------
  409. const unsigned short& PUEmitter::getParticleTextureCoords(void) const
  410. {
  411. return _particleTextureCoords;
  412. }
  413. //-----------------------------------------------------------------------
  414. void PUEmitter::setParticleTextureCoords(const unsigned short& particleTextureCoords)
  415. {
  416. _particleTextureCoords = particleTextureCoords;
  417. }
  418. //-----------------------------------------------------------------------
  419. const unsigned short& PUEmitter::getParticleTextureCoordsRangeStart(void) const
  420. {
  421. return _particleTextureCoordsRangeStart;
  422. }
  423. //-----------------------------------------------------------------------
  424. void PUEmitter::setParticleTextureCoordsRangeStart(const unsigned short& particleTextureCoordsRangeStart)
  425. {
  426. _particleTextureCoordsRangeStart = particleTextureCoordsRangeStart;
  427. _particleTextureCoordsRangeSet = true;
  428. }
  429. //-----------------------------------------------------------------------
  430. const unsigned short& PUEmitter::getParticleTextureCoordsRangeEnd(void) const
  431. {
  432. return _particleTextureCoordsRangeEnd;
  433. }
  434. //-----------------------------------------------------------------------
  435. void PUEmitter::setParticleTextureCoordsRangeEnd(const unsigned short& particleTextureCoordsRangeEnd)
  436. {
  437. _particleTextureCoordsRangeEnd = particleTextureCoordsRangeEnd;
  438. _particleTextureCoordsRangeSet = true;
  439. }
  440. //-----------------------------------------------------------------------
  441. void PUEmitter::setEmitsName(const std::string& emitsName)
  442. {
  443. _emitsName = emitsName;
  444. _emitsEntity = nullptr;
  445. //if (!_emitsName.empty())
  446. //{
  447. // markedForEmission = true;
  448. // if (mParentTechnique)
  449. // {
  450. // // Notify the Technique that something changed
  451. // mParentTechnique->_notifyEmissionChange();
  452. // }
  453. //}
  454. }
  455. //-----------------------------------------------------------------------
  456. void PUEmitter::setDynEmissionRate(PUDynamicAttribute* dynEmissionRate)
  457. {
  458. if (_dynEmissionRate)
  459. delete _dynEmissionRate;
  460. _dynEmissionRate = dynEmissionRate;
  461. }
  462. //-----------------------------------------------------------------------
  463. void PUEmitter::setDynTotalTimeToLive(PUDynamicAttribute* dynTotalTimeToLive)
  464. {
  465. if (_dynTotalTimeToLive)
  466. delete _dynTotalTimeToLive;
  467. _dynTotalTimeToLive = dynTotalTimeToLive;
  468. }
  469. //-----------------------------------------------------------------------
  470. void PUEmitter::setDynParticleMass(PUDynamicAttribute* dynParticleMass)
  471. {
  472. if (_dynParticleMass)
  473. delete _dynParticleMass;
  474. _dynParticleMass = dynParticleMass;
  475. }
  476. //-----------------------------------------------------------------------
  477. void PUEmitter::setDynAngle(PUDynamicAttribute* dynAngle)
  478. {
  479. if (_dynAngle)
  480. delete _dynAngle;
  481. _dynAngle = dynAngle;
  482. }
  483. //-----------------------------------------------------------------------
  484. void PUEmitter::setDynVelocity(PUDynamicAttribute* dynVelocity)
  485. {
  486. if (_dynVelocity)
  487. delete _dynVelocity;
  488. _dynVelocity = dynVelocity;
  489. }
  490. //-----------------------------------------------------------------------
  491. void PUEmitter::setDynDuration(PUDynamicAttribute* dynDuration)
  492. {
  493. if (_dynDuration)
  494. delete _dynDuration;
  495. _dynDuration = dynDuration;
  496. _dynDurationSet = true;
  497. initTimeBased();
  498. }
  499. //-----------------------------------------------------------------------
  500. void PUEmitter::setDynDurationSet(bool durationSet)
  501. {
  502. _dynDurationSet = durationSet;
  503. }
  504. //-----------------------------------------------------------------------
  505. void PUEmitter::setDynRepeatDelay(PUDynamicAttribute* dynRepeatDelay)
  506. {
  507. if (_dynRepeatDelay)
  508. delete _dynRepeatDelay;
  509. _dynRepeatDelay = dynRepeatDelay;
  510. _dynRepeatDelaySet = true;
  511. initTimeBased();
  512. }
  513. //-----------------------------------------------------------------------
  514. void PUEmitter::setDynRepeatDelaySet(bool repeatDelaySet)
  515. {
  516. _dynRepeatDelaySet = repeatDelaySet;
  517. }
  518. //-----------------------------------------------------------------------
  519. void PUEmitter::setDynParticleAllDimensions(PUDynamicAttribute* dynParticleAllDimensions)
  520. {
  521. if (_dynParticleAllDimensions)
  522. delete _dynParticleAllDimensions;
  523. _dynParticleAllDimensions = dynParticleAllDimensions;
  524. _dynParticleAllDimensionsSet = true;
  525. }
  526. //-----------------------------------------------------------------------
  527. void PUEmitter::setDynParticleAllDimensionsSet(bool particleAllDimensionsSet)
  528. {
  529. _dynParticleAllDimensionsSet = particleAllDimensionsSet;
  530. }
  531. //-----------------------------------------------------------------------
  532. void PUEmitter::setDynParticleWidth(PUDynamicAttribute* dynParticleWidth)
  533. {
  534. if (_dynParticleWidth)
  535. delete _dynParticleWidth;
  536. _dynParticleWidth = dynParticleWidth;
  537. _dynParticleWidthSet = true;
  538. }
  539. //-----------------------------------------------------------------------
  540. void PUEmitter::setDynParticleWidthSet(bool particleWidthSet)
  541. {
  542. _dynParticleWidthSet = particleWidthSet;
  543. }
  544. //-----------------------------------------------------------------------
  545. void PUEmitter::setDynParticleHeight(PUDynamicAttribute* dynParticleHeight)
  546. {
  547. if (_dynParticleHeight)
  548. delete _dynParticleHeight;
  549. _dynParticleHeight = dynParticleHeight;
  550. _dynParticleHeightSet = true;
  551. }
  552. //-----------------------------------------------------------------------
  553. void PUEmitter::setDynParticleHeightSet(bool particleHeightSet)
  554. {
  555. _dynParticleHeightSet = particleHeightSet;
  556. }
  557. //-----------------------------------------------------------------------
  558. void PUEmitter::setDynParticleDepth(PUDynamicAttribute* dynParticleDepth)
  559. {
  560. if (_dynParticleDepth)
  561. delete _dynParticleDepth;
  562. _dynParticleDepth = dynParticleDepth;
  563. _dynParticleDepthSet = true;
  564. }
  565. //-----------------------------------------------------------------------
  566. void PUEmitter::setDynParticleDepthSet(bool particleDepthSet)
  567. {
  568. _dynParticleDepthSet = particleDepthSet;
  569. }
  570. //-----------------------------------------------------------------------
  571. const Vec3& PUEmitter::getParticleDirection(void)
  572. {
  573. return _particleDirection;
  574. }
  575. //-----------------------------------------------------------------------
  576. void PUEmitter::setParticleDirection(const Vec3& direction)
  577. {
  578. _particleDirection = direction;
  579. _originalParticleDirection = direction;
  580. _particleDirection.normalize();
  581. _upVector = PUUtil::perpendicular(_particleDirection);
  582. _upVector.normalize();
  583. }
  584. //-----------------------------------------------------------------------
  585. const Vec3& PUEmitter::getOriginalParticleDirection(void) const
  586. {
  587. return _originalParticleDirection;
  588. }
  589. //-----------------------------------------------------------------------
  590. const Quaternion& PUEmitter::getParticleOrientation(void) const
  591. {
  592. return _particleOrientation;
  593. }
  594. //-----------------------------------------------------------------------
  595. void PUEmitter::setParticleOrientation(const Quaternion& orientation)
  596. {
  597. _particleOrientation = orientation;
  598. }
  599. //-----------------------------------------------------------------------
  600. const Quaternion& PUEmitter::getParticleOrientationRangeStart(void) const
  601. {
  602. return _particleOrientationRangeStart;
  603. }
  604. //-----------------------------------------------------------------------
  605. void PUEmitter::setParticleOrientationRangeStart(const Quaternion& orientationRangeStart)
  606. {
  607. _particleOrientationRangeStart = orientationRangeStart;
  608. _particleOrientationRangeSet = true;
  609. }
  610. //-----------------------------------------------------------------------
  611. const Quaternion& PUEmitter::getParticleOrientationRangeEnd(void) const
  612. {
  613. return _particleOrientationRangeEnd;
  614. }
  615. //-----------------------------------------------------------------------
  616. void PUEmitter::setParticleOrientationRangeEnd(const Quaternion& orientationRangeEnd)
  617. {
  618. _particleOrientationRangeEnd = orientationRangeEnd;
  619. _particleOrientationRangeSet = true;
  620. }
  621. //-----------------------------------------------------------------------
  622. bool PUEmitter::isAutoDirection(void) const
  623. {
  624. return _autoDirection;
  625. }
  626. //-----------------------------------------------------------------------
  627. void PUEmitter::setAutoDirection(bool autoDirection)
  628. {
  629. _autoDirection = autoDirection;
  630. }
  631. //-----------------------------------------------------------------------
  632. bool PUEmitter::isForceEmission(void) const
  633. {
  634. return _forceEmission;
  635. }
  636. //-----------------------------------------------------------------------
  637. void PUEmitter::setForceEmission(bool forceEmission)
  638. {
  639. _forceEmission = forceEmission;
  640. _originalForceEmission = forceEmission;
  641. _forceEmissionExecuted = false;
  642. _originalForceEmissionExecuted = false;
  643. }
  644. void PUEmitter::initTimeBased( void )
  645. {
  646. if (_isEnabled)
  647. {
  648. if (_dynDurationSet)
  649. {
  650. _durationRemain = _dynamicAttributeHelper.calculate(_dynDuration, (static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart());
  651. }
  652. /** Determine whether duration must be used. If it is used, the emitter should at least be enabled.
  653. @remarks
  654. Note, that if the duration has been exceeded, the emitter is disabled. It makes perfect sense to enable
  655. the emitter again when the duration is initialised with a valid value (> 0).
  656. */
  657. if (_durationRemain > 0)
  658. {
  659. _isEnabled = true;
  660. _repeatDelayRemain = 0;
  661. }
  662. }
  663. else
  664. {
  665. if (_dynRepeatDelaySet)
  666. {
  667. _repeatDelayRemain = _dynamicAttributeHelper.calculate(_dynRepeatDelay, (static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart());
  668. }
  669. }
  670. }
  671. void PUEmitter::initParticleForEmission( PUParticle3D* particle )
  672. {
  673. // Initialise the particle position (localspace)
  674. particle->parentEmitter = this;
  675. initParticlePosition(particle);
  676. initParticleDirection(particle);
  677. initParticleVelocity(particle);
  678. initParticleOrientation(particle);
  679. initParticleMass(particle);
  680. initParticleColor(particle);
  681. initParticleTextureCoords(particle);
  682. particle->totalTimeToLive = initParticleTimeToLive();
  683. particle->timeToLive = particle->totalTimeToLive;
  684. // Generate particles' own dimensions if defined.
  685. initParticleDimensions(particle);
  686. }
  687. void PUEmitter::initParticleVelocity( PUParticle3D* particle )
  688. {
  689. float scalar = _dynamicAttributeHelper.calculate(_dynVelocity, (static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart(), 1.0f);
  690. particle->direction *= scalar;
  691. particle->originalVelocity = scalar;
  692. particle->originalScaledDirectionLength = particle->direction.length();
  693. }
  694. void PUEmitter::initParticleMass( PUParticle3D* particle )
  695. {
  696. float mass = _dynamicAttributeHelper.calculate(_dynParticleMass, (static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart(), PUParticle3D::DEFAULT_MASS);
  697. particle->mass = mass;
  698. }
  699. void PUEmitter::initParticleColor( PUParticle3D* particle )
  700. {
  701. if (_particleColorRangeSet)
  702. {
  703. if (_particleColorRangeStart.x < _particleColorRangeEnd.x)
  704. particle->color.x = cocos2d::random(_particleColorRangeStart.x, _particleColorRangeEnd.x);
  705. else
  706. particle->color.x = cocos2d::random(_particleColorRangeEnd.x, _particleColorRangeStart.x);
  707. if (_particleColorRangeStart.y < _particleColorRangeEnd.y)
  708. particle->color.y = cocos2d::random(_particleColorRangeStart.y, _particleColorRangeEnd.y);
  709. else
  710. particle->color.y = cocos2d::random(_particleColorRangeEnd.y, _particleColorRangeStart.y);
  711. if (_particleColorRangeStart.z < _particleColorRangeEnd.z)
  712. particle->color.z = cocos2d::random(_particleColorRangeStart.z, _particleColorRangeEnd.z);
  713. else
  714. particle->color.z = cocos2d::random(_particleColorRangeEnd.z, _particleColorRangeStart.z);
  715. if (_particleColorRangeStart.w < _particleColorRangeEnd.w)
  716. particle->color.w = cocos2d::random(_particleColorRangeStart.w, _particleColorRangeEnd.w);
  717. else
  718. particle->color.w = cocos2d::random(_particleColorRangeEnd.w, _particleColorRangeStart.w);
  719. }
  720. else
  721. {
  722. particle->color = _particleColor;
  723. }
  724. // Set original colour
  725. particle->originalColor = particle->color;
  726. }
  727. void PUEmitter::initParticleTextureCoords( PUParticle3D* particle )
  728. {
  729. if (_particleTextureCoordsRangeSet)
  730. {
  731. particle->textureCoordsCurrent = (unsigned short)cocos2d::random((float)_particleTextureCoordsRangeStart, (float)_particleTextureCoordsRangeEnd + 0.999f);
  732. }
  733. else
  734. {
  735. particle->textureCoordsCurrent = _particleTextureCoords;
  736. }
  737. }
  738. float PUEmitter::initParticleTimeToLive()
  739. {
  740. return _dynamicAttributeHelper.calculate(_dynTotalTimeToLive, (static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart(), PUParticle3D::DEFAULT_TTL);
  741. }
  742. void PUEmitter::initParticleDimensions( PUParticle3D* particle )
  743. {
  744. // Only continue if one of them is set
  745. if (_dynParticleAllDimensionsSet || _dynParticleWidthSet || _dynParticleHeightSet || _dynParticleDepthSet)
  746. {
  747. // Set all dimensions equal ...
  748. float extend = 0;
  749. if (_dynParticleAllDimensionsSet && _dynParticleAllDimensions)
  750. {
  751. extend = _dynamicAttributeHelper.calculate(_dynParticleAllDimensions, (static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart());
  752. particle->setOwnDimensions(_emitterScale.x * extend, _emitterScale.y * extend, _emitterScale.z * extend);
  753. return;
  754. }
  755. // ... or set the dimensions independent from each other
  756. float width = 0;
  757. float height = 0;
  758. float depth = 0;
  759. if (_dynParticleWidthSet && _dynParticleWidth)
  760. {
  761. width = _dynamicAttributeHelper.calculate(_dynParticleWidth, (static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart());
  762. }
  763. if (_dynParticleHeightSet && _dynParticleHeight)
  764. {
  765. height = _dynamicAttributeHelper.calculate(_dynParticleHeight, (static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart());
  766. }
  767. if (_dynParticleDepthSet && _dynParticleDepth)
  768. {
  769. depth = _dynamicAttributeHelper.calculate(_dynParticleDepth, (static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart());
  770. }
  771. /** Set the width, height and depth if at least one of them is set.
  772. @remarks
  773. If one of the dimensions is 0, it will be overridden by the default value later on.
  774. */
  775. if (_dynParticleWidthSet || _dynParticleHeightSet || _dynParticleDepthSet)
  776. {
  777. particle->setOwnDimensions(_emitterScale.x * width, _emitterScale.y * height, _emitterScale.z * depth);
  778. }
  779. }
  780. else
  781. {
  782. // Just set the width, height and depth, but these are just the default settings; the particle doesn't
  783. // have own dimensions. Recalculate the bounding sphere radius.
  784. particle->width = _emitterScale.x * (static_cast<PUParticleSystem3D *>(_particleSystem))->getDefaultWidth();
  785. particle->height = _emitterScale.y * (static_cast<PUParticleSystem3D *>(_particleSystem))->getDefaultHeight();
  786. particle->depth = _emitterScale.z * (static_cast<PUParticleSystem3D *>(_particleSystem))->getDefaultDepth();
  787. particle->calculateBoundingSphereRadius();
  788. }
  789. }
  790. bool PUEmitter::isEmitterDone() const
  791. {
  792. return !(_isEnabled || _dynRepeatDelaySet);
  793. }
  794. Ref* PUEmitter::getEmitsEntityPtr() const
  795. {
  796. return _emitsEntity;
  797. }
  798. void PUEmitter::copyAttributesTo( PUEmitter* emitter )
  799. {
  800. emitter->setName(_name);
  801. emitter->setEmitterType(_emitterType);
  802. emitter->setEmitsName(_emitsName);
  803. emitter->setEmitsType(_emitsType);
  804. emitter->_position = _position;
  805. emitter->_isEnabled = _isEnabled;
  806. emitter->_originEnabled = _originEnabled;
  807. emitter->_originEnabledSet = _originEnabledSet;
  808. emitter->_particleDirection = _particleDirection;
  809. emitter->_originalParticleDirection = _originalParticleDirection;
  810. emitter->_particleOrientation = _particleOrientation;
  811. emitter->_particleOrientationRangeStart = _particleOrientationRangeStart;
  812. emitter->_particleOrientationRangeEnd = _particleOrientationRangeEnd;
  813. emitter->_particleOrientationRangeSet = _particleOrientationRangeSet;
  814. emitter->_isMarkedForEmission = _isMarkedForEmission;
  815. emitter->_particleSystem = _particleSystem;
  816. emitter->_autoDirection = _autoDirection;
  817. emitter->setForceEmission(_forceEmission);
  818. emitter->_dynDurationSet = _dynDurationSet;
  819. emitter->_dynRepeatDelaySet = _dynRepeatDelaySet;
  820. emitter->_dynParticleAllDimensionsSet = _dynParticleAllDimensionsSet;
  821. emitter->_dynParticleWidthSet = _dynParticleWidthSet;
  822. emitter->_dynParticleHeightSet = _dynParticleHeightSet;
  823. emitter->_dynParticleDepthSet = _dynParticleDepthSet;
  824. emitter->_emitterScale = _emitterScale;
  825. emitter->_particleColor = _particleColor;
  826. emitter->_particleColorRangeStart = _particleColorRangeStart;
  827. emitter->_particleColorRangeEnd = _particleColorRangeEnd;
  828. emitter->_particleColorRangeSet = _particleColorRangeSet;
  829. emitter->_particleTextureCoords = _particleTextureCoords;
  830. emitter->_particleTextureCoordsRangeStart = _particleTextureCoordsRangeStart;
  831. emitter->_particleTextureCoordsRangeEnd = _particleTextureCoordsRangeEnd;
  832. emitter->_particleTextureCoordsRangeSet = _particleTextureCoordsRangeSet;
  833. emitter->_keepLocal = _keepLocal;
  834. // Copy Dyn. Emission rate if available
  835. emitter->setDynEmissionRate(getDynEmissionRate()->clone());
  836. // Copy Dyn. Total time to live if available
  837. emitter->setDynTotalTimeToLive(getDynTotalTimeToLive()->clone());
  838. // Copy Dyn. Velocity if available
  839. emitter->setDynVelocity(getDynVelocity()->clone());
  840. // Copy Dyn. Duration if available
  841. if (_dynDurationSet)
  842. {
  843. emitter->setDynDuration(getDynDuration()->clone());
  844. }
  845. // Copy Dyn. RepeatDelay if available
  846. if (_dynRepeatDelaySet)
  847. {
  848. emitter->setDynRepeatDelay(getDynRepeatDelay()->clone());
  849. }
  850. // Copy Dyn. Particle Mass if available
  851. emitter->setDynParticleMass(getDynParticleMass()->clone());
  852. // Copy Dyn. Angle if available
  853. emitter->setDynAngle(getDynAngle()->clone());
  854. // Copy Dyn. own width, height and depth if available
  855. if (_dynParticleAllDimensionsSet)
  856. {
  857. emitter->setDynParticleAllDimensions(getDynParticleAllDimensions()->clone());
  858. }
  859. if (_dynParticleWidthSet)
  860. {
  861. emitter->setDynParticleWidth(getDynParticleWidth()->clone());
  862. }
  863. if (_dynParticleHeightSet)
  864. {
  865. emitter->setDynParticleHeight(getDynParticleHeight()->clone());
  866. }
  867. if (_dynParticleDepthSet)
  868. {
  869. emitter->setDynParticleDepth(getDynParticleDepth()->clone());
  870. }
  871. }
  872. NS_CC_END