CCPUParticleSystem3D.cpp 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435
  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 "extensions/Particle3D/PU/CCPUParticleSystem3D.h"
  22. #include "extensions/Particle3D/PU/CCPUEmitter.h"
  23. #include "extensions/Particle3D/PU/CCPUEmitterManager.h"
  24. #include "extensions/Particle3D/PU/CCPUAffector.h"
  25. #include "extensions/Particle3D/PU/CCPUAffectorManager.h"
  26. #include "extensions/Particle3D/CCParticle3DRender.h"
  27. #include "extensions/Particle3D/PU/CCPUScriptCompiler.h"
  28. #include "extensions/Particle3D/PU/CCPUMaterialManager.h"
  29. #include "extensions/Particle3D/PU/CCPUTranslateManager.h"
  30. #include "extensions/Particle3D/PU/CCPUListener.h"
  31. #include "extensions/Particle3D/PU/CCPUObserver.h"
  32. #include "extensions/Particle3D/PU/CCPUObserverManager.h"
  33. #include "extensions/Particle3D/PU/CCPUBehaviour.h"
  34. #include "platform/CCFileUtils.h"
  35. NS_CC_BEGIN
  36. float PUParticle3D::DEFAULT_TTL = 10.0f;
  37. float PUParticle3D::DEFAULT_MASS = 1.0f;
  38. float PUParticle3D::calculateVelocity() const
  39. {
  40. if (originalScaledDirectionLength != 0)
  41. {
  42. return originalVelocity * (direction.length() / originalScaledDirectionLength);
  43. }
  44. else
  45. {
  46. // Assume originalScaledDirectionLength to be 1.0 (unit vector)
  47. return originalVelocity * direction.length();
  48. }
  49. }
  50. void PUParticle3D::setOwnDimensions( float newWidth, float newHeight, float newDepth )
  51. {
  52. ownDimensions = true;
  53. if (newWidth)
  54. width = newWidth;
  55. if (newHeight)
  56. height = newHeight;
  57. if (newDepth)
  58. depth = newDepth;
  59. calculateBoundingSphereRadius();
  60. //parentEmitter->getParentTechnique()->_notifyParticleResized();
  61. }
  62. void PUParticle3D::calculateBoundingSphereRadius()
  63. {
  64. //radius = 0.5 * Math::Sqrt(width*width + height*height + depth*depth);
  65. radius = 0.5f * std::max(depth, std::max(width, height)); // approximation
  66. }
  67. void PUParticle3D::initForEmission()
  68. {
  69. eventFlags = 0;
  70. timeFraction = 0.0f;
  71. /* Note, that this flag must only be set as soon as the particle is emitted. As soon as the particle has
  72. been moved once, the flag must be removed again.
  73. */
  74. addEventFlags(PUParticle3D::PEF_EMITTED);
  75. // Reset freeze flag
  76. freezed = false;
  77. if (!behaviours.empty()){
  78. for (auto &it : behaviours) {
  79. it->initParticleForEmission(this);
  80. }
  81. }
  82. }
  83. void PUParticle3D::initForExpiration( float timeElapsed )
  84. {
  85. if (!behaviours.empty()){
  86. for (auto &it : behaviours) {
  87. it->initParticleForExpiration(this, timeElapsed);
  88. }
  89. }
  90. }
  91. void PUParticle3D::process( float timeElapsed )
  92. {
  93. timeFraction = (totalTimeToLive - timeToLive) / totalTimeToLive;
  94. if (!behaviours.empty()){
  95. for (auto &it : behaviours) {
  96. it->updateBehaviour(this, timeElapsed);
  97. }
  98. }
  99. }
  100. PUParticle3D::PUParticle3D():
  101. particleEntityPtr(nullptr),
  102. parentEmitter(nullptr),
  103. visualData(nullptr),
  104. particleType(PT_VISUAL),
  105. originalDirectionLength(0.0f),
  106. originalVelocity(0.0f),
  107. originalScaledDirectionLength(0.0f),
  108. rotationAxis(Vec3::UNIT_Z),
  109. //color(Vec4::ONE),
  110. originalColor(Vec4::ONE),
  111. //zRotation(0.0f),
  112. zRotationSpeed(0.0f),
  113. rotationSpeed(0.0f),
  114. radius(0.87f),
  115. ownDimensions(false),
  116. eventFlags(0),
  117. freezed(false),
  118. timeToLive(DEFAULT_TTL),
  119. totalTimeToLive(DEFAULT_TTL),
  120. timeFraction(0.0f),
  121. mass(DEFAULT_MASS),
  122. textureAnimationTimeStep(0.1f),
  123. textureAnimationTimeStepCount(0.0f),
  124. textureCoordsCurrent(0),
  125. textureAnimationDirectionUp(true),
  126. depthInView(0.0f),
  127. zRotation(0.0f)
  128. //widthInWorld(width),
  129. //heightInWorld(height),
  130. //depthInWorld(depth)
  131. {
  132. }
  133. PUParticle3D::~PUParticle3D()
  134. {
  135. for (auto it : behaviours) {
  136. it->release();
  137. }
  138. //CC_SAFE_RELEASE(particleEntityPtr);
  139. }
  140. void PUParticle3D::copyBehaviours( const ParticleBehaviourList &list )
  141. {
  142. for (auto it : list){
  143. auto behaviour = it->clone();
  144. behaviour->retain();
  145. behaviours.push_back(behaviour);
  146. }
  147. }
  148. //-----------------------------------------------------------------------
  149. const float PUParticleSystem3D::DEFAULT_WIDTH = 50;
  150. const float PUParticleSystem3D::DEFAULT_HEIGHT = 50;
  151. const float PUParticleSystem3D::DEFAULT_DEPTH = 50;
  152. const unsigned int PUParticleSystem3D::DEFAULT_PARTICLE_QUOTA = 500;
  153. const unsigned int PUParticleSystem3D::DEFAULT_EMITTED_EMITTER_QUOTA = 50;
  154. const unsigned int PUParticleSystem3D::DEFAULT_EMITTED_SYSTEM_QUOTA = 10;
  155. const float PUParticleSystem3D::DEFAULT_MAX_VELOCITY = 9999.0f;
  156. PUParticleSystem3D::PUParticleSystem3D()
  157. : _emittedEmitterQuota(DEFAULT_EMITTED_EMITTER_QUOTA)
  158. , _emittedSystemQuota(DEFAULT_EMITTED_SYSTEM_QUOTA)
  159. , _prepared(false)
  160. , _poolPrepared(false)
  161. , _particleSystemScaleVelocity(1.0f)
  162. , _timeElapsedSinceStart(0.0f)
  163. , _defaultWidth(DEFAULT_WIDTH)
  164. , _defaultHeight(DEFAULT_HEIGHT)
  165. , _defaultDepth(DEFAULT_DEPTH)
  166. , _maxVelocity(DEFAULT_MAX_VELOCITY)
  167. , _maxVelocitySet(false)
  168. , _isMarkedForEmission(false)
  169. , _parentParticleSystem(nullptr)
  170. {
  171. _particleQuota = DEFAULT_PARTICLE_QUOTA;
  172. }
  173. PUParticleSystem3D::~PUParticleSystem3D()
  174. {
  175. stopParticleSystem();
  176. unPrepared();
  177. _particlePool.removeAllDatas();
  178. for (auto iter : _emittedEmitterParticlePool){
  179. auto pool = iter.second;
  180. auto lockedList = pool.getUnActiveDataList();
  181. for (auto iter2 : lockedList){
  182. static_cast<PUParticle3D *>(iter2)->particleEntityPtr->release();
  183. }
  184. iter.second.removeAllDatas();
  185. }
  186. for (auto iter : _emittedSystemParticlePool){
  187. auto pool = iter.second;
  188. auto lockedList = pool.getUnActiveDataList();
  189. for (auto iter2 : lockedList){
  190. static_cast<PUParticle3D *>(iter2)->particleEntityPtr->release();
  191. }
  192. iter.second.removeAllDatas();
  193. }
  194. //release all emitters
  195. for (auto it : _emitters) {
  196. it->release();
  197. }
  198. _emitters.clear();
  199. for (auto it : _observers){
  200. it->release();
  201. }
  202. for (auto it : _behaviourTemplates) {
  203. it->release();
  204. }
  205. _observers.clear();
  206. }
  207. PUParticleSystem3D* PUParticleSystem3D::create()
  208. {
  209. auto pups = new (std::nothrow) PUParticleSystem3D();
  210. pups->autorelease();
  211. return pups;
  212. }
  213. PUParticleSystem3D* PUParticleSystem3D::create( const std::string &filePath, const std::string &materialPath )
  214. {
  215. PUParticleSystem3D *ret = new (std::nothrow) PUParticleSystem3D();
  216. if (ret && ret->initWithFilePathAndMaterialPath(filePath, materialPath))
  217. {
  218. ret->autorelease();
  219. return ret;
  220. }
  221. else
  222. {
  223. CC_SAFE_DELETE(ret);
  224. return nullptr;
  225. }
  226. }
  227. PUParticleSystem3D* PUParticleSystem3D::create( const std::string &filePath )
  228. {
  229. PUParticleSystem3D *ret = new (std::nothrow) PUParticleSystem3D();
  230. if (ret && ret->initWithFilePath(filePath))
  231. {
  232. ret->autorelease();
  233. return ret;
  234. }
  235. else
  236. {
  237. CC_SAFE_DELETE(ret);
  238. return nullptr;
  239. }
  240. }
  241. bool PUParticleSystem3D::initWithFilePath( const std::string &filePath )
  242. {
  243. std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filePath);
  244. convertToUnixStylePath(fullPath);
  245. std::string::size_type pos = fullPath.find_last_of("/");
  246. std::string materialFolder = "materials";
  247. if (pos != std::string::npos){
  248. std::string temp = fullPath.substr(0, pos);
  249. pos = temp.find_last_of("/");
  250. if (pos != std::string::npos){
  251. materialFolder = temp.substr(0, pos + 1) + materialFolder;
  252. }
  253. }
  254. static std::vector<std::string> loadedFolder;
  255. if (std::find(loadedFolder.begin(), loadedFolder.end(), materialFolder) == loadedFolder.end())
  256. {
  257. PUMaterialCache::Instance()->loadMaterialsFromSearchPaths(materialFolder);
  258. loadedFolder.push_back(materialFolder);
  259. }
  260. if (!initSystem(fullPath)){
  261. return false;
  262. }
  263. return true;
  264. }
  265. bool PUParticleSystem3D::initWithFilePathAndMaterialPath( const std::string &filePath, const std::string &materialPath )
  266. {
  267. std::string matfullPath = FileUtils::getInstance()->fullPathForFilename(materialPath);
  268. convertToUnixStylePath(matfullPath);
  269. PUMaterialCache::Instance()->loadMaterials(matfullPath);
  270. std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filePath);
  271. convertToUnixStylePath(fullPath);
  272. if (!initSystem(fullPath)){
  273. return false;
  274. }
  275. return true;
  276. }
  277. void PUParticleSystem3D::startParticleSystem()
  278. {
  279. stopParticleSystem();
  280. if (_state != State::RUNNING)
  281. {
  282. forceStopParticleSystem();
  283. if (_render)
  284. _render->notifyStart();
  285. for (auto &it : _observers){
  286. it->notifyStart();
  287. }
  288. for (auto& it : _emitters) {
  289. auto emitter = static_cast<PUEmitter*>(it);
  290. emitter->notifyStart();
  291. }
  292. for (auto& it : _affectors) {
  293. auto affector = static_cast<PUAffector*>(it);
  294. affector->notifyStart();
  295. }
  296. scheduleUpdate();
  297. _state = State::RUNNING;
  298. }
  299. for (auto iter : _children)
  300. {
  301. PUParticleSystem3D *system = dynamic_cast<PUParticleSystem3D *>(iter);
  302. if (system){
  303. system->_parentParticleSystem = this;
  304. system->startParticleSystem();
  305. }
  306. }
  307. }
  308. void PUParticleSystem3D::stopParticleSystem()
  309. {
  310. if (_state != State::STOP)
  311. {
  312. _state = State::STOP;
  313. }
  314. for (auto iter : _children)
  315. {
  316. PUParticleSystem3D *system = dynamic_cast<PUParticleSystem3D *>(iter);
  317. if (system)
  318. system->stopParticleSystem();
  319. }
  320. }
  321. void PUParticleSystem3D::pauseParticleSystem()
  322. {
  323. if (_state == State::RUNNING)
  324. {
  325. //if (_emitter)
  326. //{
  327. // auto emitter = static_cast<PUEmitter*>(_emitter);
  328. // emitter->notifyPause();
  329. //}
  330. for (auto& it : _emitters) {
  331. auto emitter = static_cast<PUEmitter*>(it);
  332. emitter->notifyPause();
  333. }
  334. for (auto& it : _affectors) {
  335. auto affector = static_cast<PUAffector*>(it);
  336. affector->notifyPause();
  337. }
  338. _state = State::PAUSE;
  339. }
  340. for (auto iter : _children)
  341. {
  342. PUParticleSystem3D *system = dynamic_cast<PUParticleSystem3D *>(iter);
  343. if (system)
  344. system->pauseParticleSystem();
  345. }
  346. }
  347. void PUParticleSystem3D::resumeParticleSystem()
  348. {
  349. if (_state == State::PAUSE)
  350. {
  351. //if (_emitter)
  352. //{
  353. // auto emitter = static_cast<PUEmitter*>(_emitter);
  354. // emitter->notifyResume();
  355. //}
  356. for (auto& it : _emitters) {
  357. auto emitter = static_cast<PUEmitter*>(it);
  358. emitter->notifyResume();
  359. }
  360. for (auto& it : _affectors) {
  361. auto affector = static_cast<PUAffector*>(it);
  362. affector->notifyResume();
  363. }
  364. _state = State::RUNNING;
  365. }
  366. for (auto iter : _children)
  367. {
  368. PUParticleSystem3D *system = dynamic_cast<PUParticleSystem3D *>(iter);
  369. if (system)
  370. system->resumeParticleSystem();
  371. }
  372. }
  373. void PUParticleSystem3D::update(float delta)
  374. {
  375. if (!_isEnabled || _isMarkedForEmission) return;
  376. if (_state != State::RUNNING){
  377. if (_state == State::PAUSE)
  378. return;
  379. else if (_state == State::STOP && getAliveParticleCount() <= 0){
  380. forceStopParticleSystem();
  381. return;
  382. }
  383. }
  384. forceUpdate(delta);
  385. }
  386. void PUParticleSystem3D::forceUpdate( float delta )
  387. {
  388. if (!_emitters.empty())
  389. calulateRotationOffset();
  390. prepared();
  391. Vec3 currentPos = getDerivedPosition();
  392. _latestPositionDiff = currentPos - _latestPosition;
  393. _latestPosition = currentPos;
  394. _latestOrientation = getDerivedOrientation();
  395. if (!_emitters.empty()){
  396. emitParticles(delta);
  397. preUpdator(delta);
  398. updator(delta);
  399. postUpdator(delta);
  400. }
  401. _timeElapsedSinceStart += delta;
  402. }
  403. float PUParticleSystem3D::getParticleSystemScaleVelocity() const
  404. {
  405. return _particleSystemScaleVelocity;
  406. }
  407. void PUParticleSystem3D::rotationOffset( Vec3& pos )
  408. {
  409. Mat4 rotMat;
  410. Mat4::createRotation(_rotationOffset, &rotMat);
  411. pos = _rotationCentre + rotMat * (pos - _rotationCentre);
  412. }
  413. void PUParticleSystem3D::prepared()
  414. {
  415. if (!_prepared){
  416. //if (_emitter && _emitter->isEnabled())
  417. //{
  418. // auto emitter = static_cast<PUEmitter*>(_emitter);
  419. // emitter->prepare();
  420. //}
  421. if (_render)
  422. static_cast<PURender *>(_render)->prepare();
  423. for (auto it : _behaviourTemplates) {
  424. it->prepare();
  425. }
  426. for (auto it : _emitters) {
  427. //if (it->isEnabled())
  428. (static_cast<PUEmitter*>(it))->prepare();
  429. }
  430. for (auto it : _affectors) {
  431. //if (it->isEnabled())
  432. (static_cast<PUAffector*>(it))->prepare();
  433. }
  434. if (!_poolPrepared){
  435. for (auto it : _emitters) {
  436. //if (it->isEnabled())
  437. PUEmitter *emitter = static_cast<PUEmitter*>(it);
  438. if (emitter->getEmitsType() == PUParticle3D::PT_EMITTER){
  439. PUEmitter *emitted = static_cast<PUEmitter*>(emitter->getEmitsEntityPtr());
  440. for (unsigned int i = 0; i < _emittedEmitterQuota; ++i){
  441. auto p = new (std::nothrow) PUParticle3D();
  442. p->particleType = PUParticle3D::PT_EMITTER;
  443. p->particleEntityPtr = emitted->clone();
  444. p->particleEntityPtr->retain();
  445. p->copyBehaviours(_behaviourTemplates);
  446. _emittedEmitterParticlePool[emitted->getName()].addData(p);
  447. }
  448. }
  449. else if (emitter->getEmitsType() == PUParticle3D::PT_TECHNIQUE){
  450. PUParticleSystem3D *emitted = static_cast<PUParticleSystem3D*>(emitter->getEmitsEntityPtr());
  451. for (unsigned int i = 0; i < _emittedSystemQuota; ++i){
  452. PUParticleSystem3D *clonePS = emitted->clone();
  453. auto p = new (std::nothrow) PUParticle3D();
  454. p->particleType = PUParticle3D::PT_TECHNIQUE;
  455. p->particleEntityPtr = clonePS;
  456. p->particleEntityPtr->retain();
  457. p->copyBehaviours(_behaviourTemplates);
  458. _emittedSystemParticlePool[emitted->getName()].addData(p);
  459. clonePS->prepared();
  460. }
  461. //emitted->stopParticle();
  462. }
  463. }
  464. for (unsigned int i = 0; i < _particleQuota; ++i){
  465. auto p = new (std::nothrow) PUParticle3D();
  466. p->copyBehaviours(_behaviourTemplates);
  467. _particlePool.addData(p);
  468. }
  469. _poolPrepared = true;
  470. }
  471. _prepared = true;
  472. _timeElapsedSinceStart = 0.0f;
  473. _latestPosition = getDerivedPosition(); // V1.3.1
  474. if (_parentParticleSystem){
  475. _particleSystemScaleVelocity = _parentParticleSystem->getParticleSystemScaleVelocity();
  476. }
  477. }
  478. if (!_emitters.empty())
  479. notifyRescaled(getDerivedScale());
  480. }
  481. void PUParticleSystem3D::unPrepared()
  482. {
  483. //if (_emitter && _emitter->isEnabled())
  484. //{
  485. // auto emitter = static_cast<PUEmitter*>(_emitter);
  486. // emitter->unPrepare();
  487. //}
  488. if (_prepared){
  489. if (_render)
  490. static_cast<PURender *>(_render)->unPrepare();
  491. for (auto it : _behaviourTemplates) {
  492. it->unPrepare();
  493. }
  494. for (auto it : _emitters) {
  495. if (it->isEnabled())
  496. (static_cast<PUEmitter*>(it))->unPrepare();
  497. }
  498. for (auto it : _affectors) {
  499. if (it->isEnabled())
  500. (static_cast<PUAffector*>(it))->unPrepare();
  501. }
  502. _particlePool.lockAllDatas();
  503. for (auto &iter : _emittedEmitterParticlePool){
  504. PUParticle3D *particle = static_cast<PUParticle3D *>(iter.second.getFirst());
  505. while (particle)
  506. {
  507. static_cast<PUEmitter*>(particle->particleEntityPtr)->unPrepare();
  508. particle = static_cast<PUParticle3D *>(iter.second.getNext());
  509. }
  510. iter.second.lockAllDatas();
  511. }
  512. for (auto &iter : _emittedSystemParticlePool){
  513. PUParticle3D *particle = static_cast<PUParticle3D *>(iter.second.getFirst());
  514. while (particle)
  515. {
  516. static_cast<PUParticleSystem3D*>(particle->particleEntityPtr)->unPrepared();
  517. particle = static_cast<PUParticle3D *>(iter.second.getNext());
  518. }
  519. iter.second.lockAllDatas();
  520. }
  521. _prepared = false;
  522. }
  523. }
  524. void PUParticleSystem3D::preUpdator( float elapsedTime )
  525. {
  526. //if (_emitter && _emitter->isEnabled())
  527. //{
  528. // auto emitter = static_cast<PUEmitter*>(_emitter);
  529. // emitter->preUpdateEmitter(elapsedTime);
  530. //}
  531. //bool hasNoEmitted = true;
  532. for (auto it : _emitters) {
  533. if (!it->isEmitterDone()){
  534. (static_cast<PUEmitter*>(it))->preUpdateEmitter(elapsedTime);
  535. //hasNoEmitted = false;
  536. }
  537. }
  538. //if (hasNoEmitted){
  539. // if (_particlePool.getActiveParticleList().empty())
  540. // stopParticle();
  541. //}
  542. for (auto it : _affectors) {
  543. if (it->isEnabled()){
  544. (static_cast<PUAffector*>(it))->preUpdateAffector(elapsedTime);
  545. }
  546. }
  547. for (auto it : _observers){
  548. if (it->isEnabled()){
  549. it->preUpdateObserver(elapsedTime);
  550. }
  551. }
  552. for (auto &iter : _emittedEmitterParticlePool){
  553. PUParticle3D *particle = static_cast<PUParticle3D *>(iter.second.getFirst());
  554. while (particle)
  555. {
  556. static_cast<PUEmitter*>(particle->particleEntityPtr)->preUpdateEmitter(elapsedTime);
  557. particle = static_cast<PUParticle3D *>(iter.second.getNext());
  558. }
  559. }
  560. for (auto &iter : _emittedSystemParticlePool){
  561. PUParticle3D *particle = static_cast<PUParticle3D *>(iter.second.getFirst());
  562. while (particle)
  563. {
  564. static_cast<PUParticleSystem3D*>(particle->particleEntityPtr)->preUpdator(elapsedTime);
  565. particle = static_cast<PUParticle3D *>(iter.second.getNext());
  566. }
  567. }
  568. }
  569. void PUParticleSystem3D::updator( float elapsedTime )
  570. {
  571. bool firstActiveParticle = true;
  572. bool firstParticle = true;
  573. processParticle(_particlePool, firstActiveParticle, firstParticle, elapsedTime);
  574. for (auto &iter : _emittedEmitterParticlePool){
  575. processParticle(iter.second, firstActiveParticle, firstParticle, elapsedTime);
  576. }
  577. for (auto &iter : _emittedSystemParticlePool){
  578. processParticle(iter.second, firstActiveParticle, firstParticle, elapsedTime);
  579. }
  580. }
  581. void PUParticleSystem3D::postUpdator( float elapsedTime )
  582. {
  583. //if (_emitter && _emitter->isEnabled())
  584. //{
  585. // auto emitter = static_cast<PUEmitter*>(_emitter);
  586. // emitter->postUpdateEmitter(elapsedTime);
  587. //}
  588. for (auto it : _emitters) {
  589. if (it->isEnabled()){
  590. (static_cast<PUEmitter*>(it))->postUpdateEmitter(elapsedTime);
  591. }
  592. }
  593. for (auto it : _affectors) {
  594. if (it->isEnabled())
  595. {
  596. auto affector = static_cast<PUAffector*>(it);
  597. affector->postUpdateAffector(elapsedTime);
  598. }
  599. }
  600. for (auto it : _observers){
  601. if (it->isEnabled()){
  602. it->postUpdateObserver(elapsedTime);
  603. }
  604. }
  605. for (auto &iter : _emittedEmitterParticlePool){
  606. PUParticle3D *particle = static_cast<PUParticle3D *>(iter.second.getFirst());
  607. while (particle)
  608. {
  609. static_cast<PUEmitter*>(particle->particleEntityPtr)->postUpdateEmitter(elapsedTime);
  610. particle = static_cast<PUParticle3D *>(iter.second.getNext());
  611. }
  612. }
  613. for (auto &iter : _emittedSystemParticlePool){
  614. PUParticle3D *particle = static_cast<PUParticle3D *>(iter.second.getFirst());
  615. while (particle)
  616. {
  617. static_cast<PUParticleSystem3D*>(particle->particleEntityPtr)->postUpdator(elapsedTime);
  618. particle = static_cast<PUParticle3D *>(iter.second.getNext());
  619. }
  620. }
  621. }
  622. void PUParticleSystem3D::emitParticles( float elapsedTime )
  623. {
  624. //Vec3 scale = getDerivedScale();
  625. for (auto iter : _emitters){
  626. //if (!_emitter) return;
  627. //auto emitter = static_cast<PUEmitter*>(_emitter);
  628. auto emitter = iter;
  629. //emitter->notifyRescaled(scale);
  630. if (!iter->isMarkedForEmission()){
  631. unsigned short requested = emitter->calculateRequestedParticles(elapsedTime);
  632. executeEmitParticles(emitter, requested, elapsedTime);
  633. }
  634. }
  635. }
  636. float PUParticleSystem3D::getDefaultWidth() const
  637. {
  638. return _defaultWidth;
  639. }
  640. void PUParticleSystem3D::setDefaultWidth( const float width )
  641. {
  642. _defaultWidth = width;
  643. }
  644. float PUParticleSystem3D::getDefaultHeight() const
  645. {
  646. return _defaultHeight;
  647. }
  648. void PUParticleSystem3D::setDefaultHeight( const float height )
  649. {
  650. _defaultHeight = height;
  651. }
  652. float PUParticleSystem3D::getDefaultDepth() const
  653. {
  654. return _defaultDepth;
  655. }
  656. void PUParticleSystem3D::setDefaultDepth( const float depth )
  657. {
  658. _defaultDepth = depth;
  659. }
  660. bool PUParticleSystem3D::isExpired( PUParticle3D* particle, float timeElapsed )
  661. {
  662. bool expired = particle->timeToLive < timeElapsed;
  663. if (expired)
  664. {
  665. // Set the flag to indicate that the particle has been expired
  666. particle->addEventFlags(PUParticle3D::PEF_EXPIRED);
  667. }
  668. return expired;
  669. }
  670. cocos2d::Vec3 PUParticleSystem3D::getDerivedPosition()
  671. {
  672. //if (_parentParticleSystem && _parentParticleSystem->isKeepLocal()) return Vec3::ZERO;
  673. //if (_keepLocal) return Vec3::ZERO;
  674. if (_isMarkedForEmission){
  675. return Vec3(_position.x, _position.y, _positionZ);
  676. }else{
  677. Mat4 mat = getNodeToWorldTransform();
  678. return Vec3(mat.m[12], mat.m[13], mat.m[14]);
  679. }
  680. }
  681. cocos2d::Quaternion PUParticleSystem3D::getDerivedOrientation()
  682. {
  683. //if (_parentParticleSystem && _parentParticleSystem->isKeepLocal()) return Quaternion();
  684. //if (_keepLocal) return Quaternion();
  685. if (_isMarkedForEmission){
  686. return getRotationQuat();
  687. }else{
  688. Quaternion q;
  689. Mat4 mat = getNodeToWorldTransform();
  690. mat.decompose(nullptr, &q, nullptr);
  691. return q;
  692. }
  693. }
  694. cocos2d::Vec3 PUParticleSystem3D::getDerivedScale()
  695. {
  696. //if (_parentParticleSystem && _parentParticleSystem->isKeepLocal()) return Vec3::ONE;
  697. //if (_keepLocal) return Vec3::ONE;
  698. if (_isMarkedForEmission){
  699. return Vec3(_scaleX, _scaleY, _scaleZ);
  700. }else{
  701. Vec3 s;
  702. Mat4 mat = getNodeToWorldTransform();
  703. mat.decompose(&s, nullptr, nullptr);
  704. return s;
  705. }
  706. }
  707. float PUParticleSystem3D::getMaxVelocity() const
  708. {
  709. return _maxVelocity;
  710. }
  711. void PUParticleSystem3D::setMaxVelocity( float maxVelocity )
  712. {
  713. _maxVelocity = maxVelocity;
  714. _maxVelocitySet = true;
  715. }
  716. bool PUParticleSystem3D::initSystem( const std::string &filePath )
  717. {
  718. bool isFirstCompile = true;
  719. auto list = PUScriptCompiler::Instance()->compile(filePath, isFirstCompile);
  720. if (list == nullptr || list->empty()) return false;
  721. PUTranslateManager::Instance()->translateParticleSystem(this, list);
  722. //std::string data = FileUtils::getInstance()->getStringFromFile(filePath);
  723. return true;
  724. }
  725. void PUParticleSystem3D::addEmitter( PUEmitter* emitter )
  726. {
  727. if (emitter && std::find(_emitters.begin(), _emitters.end(), emitter) == _emitters.end()){
  728. emitter->_particleSystem = this;
  729. emitter->retain();
  730. _emitters.push_back(emitter);
  731. }
  732. }
  733. PUAffector* PUParticleSystem3D::getAffector( const std::string &name )
  734. {
  735. for (auto iter : _affectors){
  736. auto pa = static_cast<PUAffector *>(iter);
  737. if (pa->getName() == name)
  738. return pa;
  739. }
  740. return nullptr;
  741. }
  742. PUEmitter* PUParticleSystem3D::getEmitter( const std::string &name )
  743. {
  744. for (auto iter : _emitters){
  745. auto pe = static_cast<PUEmitter *>(iter);
  746. if (pe->getName() == name)
  747. return pe;
  748. }
  749. return nullptr;
  750. }
  751. void PUParticleSystem3D::addListener( PUListener *listener )
  752. {
  753. auto iter = std::find(_listeners.begin(), _listeners.end(), listener);
  754. if (iter == _listeners.end()){
  755. _listeners.push_back(listener);
  756. }
  757. }
  758. void PUParticleSystem3D::removeListener( PUListener *listener )
  759. {
  760. auto iter = std::find(_listeners.begin(), _listeners.end(), listener);
  761. if (iter != _listeners.end()){
  762. _listeners.erase(iter);
  763. }
  764. }
  765. void PUParticleSystem3D::forceEmission( PUEmitter* emitter, unsigned requested )
  766. {
  767. // Fast rejection: Don't emit if the technique is not enabled
  768. if (!_isEnabled)
  769. return;
  770. executeEmitParticles(emitter, requested, 0);
  771. }
  772. void PUParticleSystem3D::executeEmitParticles( PUEmitter* emitter, unsigned requested, float elapsedTime )
  773. {
  774. if (_state == State::STOP) return;
  775. if (emitter->getEmitsType() == PUParticle3D::PT_VISUAL){
  776. emitParticles(_particlePool, emitter, requested, elapsedTime);
  777. }else if (emitter->getEmitsType() == PUParticle3D::PT_EMITTER){
  778. emitParticles(_emittedEmitterParticlePool[emitter->getEmitsName()], emitter, requested, elapsedTime);
  779. }else if (emitter->getEmitsType() == PUParticle3D::PT_TECHNIQUE){
  780. emitParticles(_emittedSystemParticlePool[emitter->getEmitsName()], emitter, requested, elapsedTime);
  781. }
  782. }
  783. void PUParticleSystem3D::emitParticles( ParticlePool &pool, PUEmitter* emitter, unsigned requested, float elapsedTime )
  784. {
  785. Vec3 scale = getDerivedScale();
  786. Mat4 rotMat;
  787. Mat4::createRotation(getDerivedOrientation(), &rotMat);
  788. float timePoint = 0.0f;
  789. float timeInc = elapsedTime / requested;
  790. for (unsigned short i = 0; i < requested; ++i)
  791. {
  792. PUParticle3D *particle = static_cast<PUParticle3D *>(pool.createData());
  793. if (!particle)
  794. return;
  795. particle->initForEmission();
  796. emitter->initParticleForEmission(particle);
  797. particle->direction = (rotMat * Vec3(particle->direction.x, particle->direction.y, particle->direction.z));
  798. particle->originalDirection = (rotMat * Vec3(particle->originalDirection.x, particle->originalDirection.y, particle->originalDirection.z));
  799. for (auto& it : _affectors) {
  800. if (it->isEnabled())
  801. {
  802. (static_cast<PUAffector*>(it))->initParticleForEmission(particle);
  803. }
  804. }
  805. initParticleForEmission(particle);
  806. particle->position.add(particle->direction.x * scale.x * _particleSystemScaleVelocity * timePoint
  807. , particle->direction.y * scale.y * _particleSystemScaleVelocity * timePoint
  808. , particle->direction.z * scale.z * _particleSystemScaleVelocity * timePoint);
  809. // Increment time fragment
  810. timePoint += timeInc;
  811. }
  812. }
  813. void PUParticleSystem3D::addObserver( PUObserver *observer )
  814. {
  815. auto iter = std::find(_observers.begin(), _observers.end(), observer);
  816. if (iter == _observers.end()){
  817. observer->retain();
  818. observer->_particleSystem = this;
  819. _observers.push_back(observer);
  820. }
  821. }
  822. PUObserver* PUParticleSystem3D::getObserver( const std::string &name )
  823. {
  824. for (auto iter : _observers){
  825. auto po = static_cast<PUObserver *>(iter);
  826. if (po->getName() == name)
  827. return po;
  828. }
  829. return nullptr;
  830. }
  831. void PUParticleSystem3D::notifyRescaled(const Vec3 &scl)
  832. {
  833. if (_render)
  834. _render->notifyRescaled(scl);
  835. for (auto it : _emitters) {
  836. (static_cast<PUEmitter*>(it))->notifyRescaled(scl);
  837. }
  838. for (auto it : _affectors) {
  839. (static_cast<PUAffector*>(it))->notifyRescaled(scl);
  840. }
  841. for (auto it : _observers){
  842. it->notifyRescaled(scl);
  843. }
  844. for (auto &iter : _emittedEmitterParticlePool){
  845. PUParticle3D *particle = static_cast<PUParticle3D *>(iter.second.getFirst());
  846. while (particle)
  847. {
  848. static_cast<PUEmitter*>(particle->particleEntityPtr)->notifyRescaled(scl);
  849. particle = static_cast<PUParticle3D *>(iter.second.getNext());
  850. }
  851. }
  852. for (auto &iter : _emittedSystemParticlePool){
  853. PUParticle3D *particle = static_cast<PUParticle3D *>(iter.second.getFirst());
  854. while (particle)
  855. {
  856. static_cast<PUParticleSystem3D*>(particle->particleEntityPtr)->notifyRescaled(scl);
  857. particle = static_cast<PUParticle3D *>(iter.second.getNext());
  858. }
  859. }
  860. }
  861. void PUParticleSystem3D::initParticleForExpiration( PUParticle3D* particle, float timeElapsed )
  862. {
  863. if (particle->particleType == PUParticle3D::PT_EMITTER){
  864. PUEmitter *emitter = static_cast<PUEmitter *>(particle->particleEntityPtr);
  865. emitter->unPrepare();
  866. }else if (particle->particleType == PUParticle3D::PT_TECHNIQUE){
  867. PUParticleSystem3D *system = static_cast<PUParticleSystem3D *>(particle->particleEntityPtr);
  868. system->unPrepared();
  869. }
  870. particle->initForExpiration(timeElapsed);
  871. for (auto it : _listeners){
  872. it->particleExpired(this, particle);
  873. }
  874. ///** Externs are also called to perform expiration activities. If needed, affectors and emitters may be added, but at the moment
  875. // there is no reason for (and we don't want to waste cpu resources).
  876. //*/
  877. //if (!mExterns.empty())
  878. //{
  879. // ExternIterator itExtern;
  880. // ExternIterator itExternEnd = mExterns.end();
  881. // for (itExtern = mExterns.begin(); itExtern != itExternEnd; ++itExtern)
  882. // {
  883. // (*itExtern)->_initParticleForExpiration(particle);
  884. // }
  885. //}
  886. }
  887. void PUParticleSystem3D::initParticleForEmission( PUParticle3D* particle )
  888. {
  889. for (auto it : _listeners){
  890. it->particleEmitted(this, particle);
  891. }
  892. }
  893. void PUParticleSystem3D::addBehaviourTemplate( PUBehaviour *behaviour )
  894. {
  895. auto iter = std::find(_behaviourTemplates.begin(), _behaviourTemplates.end(), behaviour);
  896. if (iter == _behaviourTemplates.end()){
  897. behaviour->retain();
  898. behaviour->_particleSystem = this;
  899. _behaviourTemplates.push_back(behaviour);
  900. }
  901. }
  902. void PUParticleSystem3D::convertToUnixStylePath( std::string &path )
  903. {
  904. #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
  905. for (auto &iter : path){
  906. if (iter == '\\') iter = '/';
  907. }
  908. #else
  909. CC_UNUSED_PARAM(path);
  910. #endif
  911. }
  912. void PUParticleSystem3D::clearAllParticles()
  913. {
  914. _particlePool.lockAllDatas();
  915. for (auto &iter : _emittedEmitterParticlePool){
  916. iter.second.lockAllDatas();
  917. }
  918. for (auto &iter : _emittedSystemParticlePool){
  919. iter.second.lockAllDatas();
  920. }
  921. }
  922. void PUParticleSystem3D::copyAttributesTo(PUParticleSystem3D* system )
  923. {
  924. system->removeAllEmitter();
  925. system->removeAllAffector();
  926. system->removerAllObserver();
  927. system->removeAllBehaviourTemplate();
  928. system->removeAllListener();
  929. system->_particlePool.removeAllDatas();
  930. for (auto iter : system->_emittedEmitterParticlePool){
  931. iter.second.removeAllDatas();
  932. }
  933. for (auto iter : system->_emittedSystemParticlePool){
  934. iter.second.removeAllDatas();
  935. }
  936. system->setName(_name);
  937. system->_state = _state;
  938. if (_render)
  939. system->setRender(static_cast<PURender *>(_render)->clone());
  940. system->_particleQuota = _particleQuota;
  941. system->_blend = _blend;
  942. system->_keepLocal = _keepLocal;
  943. system->_isEnabled = _isEnabled;
  944. for (auto iter : _affectors){
  945. PUAffector *affector = static_cast<PUAffector *>(iter);
  946. PUAffector *copy = PUAffectorManager::Instance()->createAffector(affector->getAffectorType());
  947. affector->copyAttributesTo(copy);
  948. system->addAffector(copy);
  949. }
  950. for (auto iter : _emitters){
  951. PUEmitter *emitter = static_cast<PUEmitter *>(iter);
  952. PUEmitter *copy = PUEmitterManager::Instance()->createEmitter(emitter->getEmitterType());
  953. emitter->copyAttributesTo(copy);
  954. system->addEmitter(copy);
  955. }
  956. for (auto iter : _observers){
  957. PUObserver *observer = static_cast<PUObserver *>(iter);
  958. PUObserver *copy = PUObserverManager::Instance()->createObserver(observer->getObserverType());
  959. observer->copyAttributesTo(copy);
  960. system->addObserver(copy);
  961. }
  962. for (auto iter : _behaviourTemplates){
  963. PUBehaviour *behaviour = static_cast<PUBehaviour *>(iter);
  964. PUBehaviour *copy = behaviour->clone();
  965. system->addBehaviourTemplate(copy);
  966. }
  967. system->_emittedEmitterQuota = _emittedEmitterQuota;
  968. system->_emittedSystemQuota = _emittedSystemQuota;
  969. system->_prepared = false;
  970. system->_particleSystemScaleVelocity = _particleSystemScaleVelocity;
  971. system->_defaultWidth = _defaultWidth;
  972. system->_defaultHeight = _defaultHeight;
  973. system->_defaultDepth = _defaultDepth;
  974. system->_maxVelocity = _maxVelocity;
  975. system->_maxVelocitySet = _maxVelocitySet;
  976. system->_matName = _matName;
  977. system->_isMarkedForEmission = _isMarkedForEmission;
  978. system->_parentParticleSystem = _parentParticleSystem;
  979. }
  980. PUParticleSystem3D* PUParticleSystem3D::clone()
  981. {
  982. auto ps = PUParticleSystem3D::create();
  983. copyAttributesTo(ps);
  984. for (auto &iter : _children){
  985. PUParticleSystem3D *child = dynamic_cast<PUParticleSystem3D *>(iter);
  986. if (child)
  987. ps->addChild(child->clone());
  988. }
  989. return ps;
  990. }
  991. void PUParticleSystem3D::removeAllEmitter()
  992. {
  993. for (auto iter : _emitters){
  994. iter->release();
  995. }
  996. _emitters.clear();
  997. }
  998. void PUParticleSystem3D::removerAllObserver()
  999. {
  1000. for (auto iter : _observers){
  1001. iter->release();
  1002. }
  1003. _observers.clear();
  1004. }
  1005. void PUParticleSystem3D::removeAllBehaviourTemplate()
  1006. {
  1007. for (auto iter : _behaviourTemplates){
  1008. iter->release();
  1009. }
  1010. _behaviourTemplates.clear();
  1011. }
  1012. void PUParticleSystem3D::removeAllListener()
  1013. {
  1014. _listeners.clear();
  1015. }
  1016. void PUParticleSystem3D::draw( Renderer *renderer, const Mat4 &transform, uint32_t flags )
  1017. {
  1018. if (!_isEnabled) return;
  1019. if (getAliveParticleCount() <= 0) return;
  1020. if (_render)
  1021. _render->render(renderer, transform, this);
  1022. if (!_emittedSystemParticlePool.empty())
  1023. {
  1024. for (auto &iter : _emittedSystemParticlePool)
  1025. {
  1026. PUParticle3D *particle = static_cast<PUParticle3D *>(iter.second.getFirst());
  1027. while (particle)
  1028. {
  1029. static_cast<PUParticleSystem3D *>(particle->particleEntityPtr)->draw(renderer, transform, flags);
  1030. particle = static_cast<PUParticle3D *>(iter.second.getNext());
  1031. }
  1032. }
  1033. }
  1034. }
  1035. void PUParticleSystem3D::processParticle( ParticlePool &pool, bool &firstActiveParticle, bool &firstParticle, float elapsedTime )
  1036. {
  1037. Vec3 scale = getDerivedScale();
  1038. PUParticle3D *particle = static_cast<PUParticle3D *>(pool.getFirst());
  1039. //Mat4 ltow = getNodeToWorldTransform();
  1040. //Vec3 scl;
  1041. //Quaternion rot;
  1042. //ltow.decompose(&scl, &rot, nullptr);
  1043. while (particle){
  1044. if (!isExpired(particle, elapsedTime)){
  1045. particle->process(elapsedTime);
  1046. //if (_emitter && _emitter->isEnabled())
  1047. // _emitter->updateEmitter(particle, elapsedTime);
  1048. for (auto it : _emitters) {
  1049. if (it->isEnabled() && !it->isMarkedForEmission()){
  1050. (static_cast<PUEmitter*>(it))->updateEmitter(particle, elapsedTime);
  1051. }
  1052. }
  1053. for (auto& it : _affectors) {
  1054. if (it->isEnabled()){
  1055. (static_cast<PUAffector*>(it))->process(particle, elapsedTime, firstActiveParticle);
  1056. }
  1057. }
  1058. if (_render)
  1059. static_cast<PURender *>(_render)->updateRender(particle, elapsedTime, firstActiveParticle);
  1060. if (_isEnabled && particle->particleType != PUParticle3D::PT_VISUAL){
  1061. if (particle->particleType == PUParticle3D::PT_EMITTER){
  1062. auto emitter = static_cast<PUEmitter *>(particle->particleEntityPtr);
  1063. emitter->setLocalPosition(particle->position);
  1064. executeEmitParticles(emitter, emitter->calculateRequestedParticles(elapsedTime), elapsedTime);
  1065. }else if (particle->particleType == PUParticle3D::PT_TECHNIQUE){
  1066. auto system = static_cast<PUParticleSystem3D *>(particle->particleEntityPtr);
  1067. system->setPosition3D(particle->position);
  1068. system->setRotationQuat(particle->orientation);
  1069. //system->setScaleX(scl.x);system->setScaleY(scl.y);system->setScaleZ(scl.z);
  1070. system->forceUpdate(elapsedTime);
  1071. }
  1072. }
  1073. firstActiveParticle = false;
  1074. // Keep latest position
  1075. particle->latestPosition = particle->position;
  1076. //if (_maxVelocitySet && particle->calculateVelocity() > _maxVelocity)
  1077. //{
  1078. // particle->direction *= (_maxVelocity / particle->direction.length());
  1079. //}
  1080. //// Update the position with the direction.
  1081. //particle->position += (particle->direction * _particleSystemScaleVelocity * elapsedTime);
  1082. //particle->positionInWorld = particle->position;
  1083. //particle->orientationInWorld = particle->orientation;
  1084. //particle->widthInWorld = particle->width;
  1085. //particle->heightInWorld = particle->height;
  1086. //particle->depthInWorld = particle->depth;
  1087. //bool keepLocal = _keepLocal;
  1088. //PUParticleSystem3D *parent = dynamic_cast<PUParticleSystem3D *>(getParent());
  1089. //if (parent) keepLocal = keepLocal || parent->isKeepLocal();
  1090. //if (keepLocal){
  1091. // ltow.transformPoint(particle->positionInWorld, &particle->positionInWorld);
  1092. // Vec3 ori;
  1093. // ltow.transformVector(Vec3(particle->orientation.x, particle->orientation.y, particle->orientation.z), &ori);
  1094. // particle->orientationInWorld.x = ori.x; particle->orientationInWorld.y = ori.y; particle->orientationInWorld.z = ori.z;
  1095. // particle->widthInWorld = scl.x * particle->width;
  1096. // particle->heightInWorld = scl.y * particle->height;
  1097. // particle->depthInWorld = scl.z * particle->depth;
  1098. //}
  1099. processMotion(particle, elapsedTime, scale, firstActiveParticle);
  1100. }
  1101. else{
  1102. initParticleForExpiration(particle, elapsedTime);
  1103. pool.lockLatestData();
  1104. }
  1105. for (auto it : _observers){
  1106. if (it->isEnabled()){
  1107. it->updateObserver(particle, elapsedTime, firstParticle);
  1108. }
  1109. }
  1110. if (particle->hasEventFlags(PUParticle3D::PEF_EXPIRED))
  1111. {
  1112. particle->setEventFlags(0);
  1113. particle->addEventFlags(PUParticle3D::PEF_EXPIRED);
  1114. }
  1115. else
  1116. {
  1117. particle->setEventFlags(0);
  1118. }
  1119. particle->timeToLive -= elapsedTime;
  1120. firstParticle = false;
  1121. particle = static_cast<PUParticle3D *>(pool.getNext());
  1122. }
  1123. }
  1124. bool PUParticleSystem3D::makeParticleLocal( PUParticle3D* particle )
  1125. {
  1126. if (!particle)
  1127. return true;
  1128. if (!_keepLocal)
  1129. return false;
  1130. particle->position += _latestPositionDiff;
  1131. return true;
  1132. }
  1133. void PUParticleSystem3D::processMotion( PUParticle3D* particle, float timeElapsed, const Vec3 &scl, bool /*firstParticle*/ )
  1134. {
  1135. if (particle->isFreezed())
  1136. return;
  1137. /** Because everything is calculated in worldspace we recalculate it back to the techniques' origin (the result is still
  1138. worldspace) just by adding a relative offset of the particle system, technique, emitter or visual particle.
  1139. Change in V1.4:
  1140. The additional PEF_EMITTED check fixes the problem with scenenodese moving forward at extremely fast speeds
  1141. The bug is due to how PU code processes keep_local, and the calculation shouldn't be applied to newly emitted particles.
  1142. */
  1143. if (!particle->hasEventFlags(PUParticle3D::PEF_EMITTED))
  1144. {
  1145. if (!particle->parentEmitter->makeParticleLocal(particle))
  1146. {
  1147. if (!makeParticleLocal(particle))
  1148. {
  1149. _parentParticleSystem->makeParticleLocal(particle);
  1150. }
  1151. }
  1152. }
  1153. /** Adjust position of the particle if the parent has rotated (only in case of particle system with 'keep local').
  1154. PU 1.4: Added check that technique may not be local, otherwise particles are rotated twice as fast.
  1155. */
  1156. if (_parentParticleSystem->isKeepLocal() && !_keepLocal)
  1157. {
  1158. /** Ignore some rendersystems, because they are rotated by Ogre itself.
  1159. Entities for example are always rotated (even if not local), based on the node orientation. A Billboard not.
  1160. */
  1161. if (_render && !static_cast<PURender *>(_render)->autoRotate)
  1162. {
  1163. _parentParticleSystem->rotationOffset(particle->position);
  1164. }
  1165. }
  1166. // Added for 1.3
  1167. if (particle->hasEventFlags(PUParticle3D::PEF_EMITTED))
  1168. return;
  1169. // Adjust the velocity to the allowed maximum.
  1170. if (_maxVelocitySet && particle->calculateVelocity() > _maxVelocity)
  1171. {
  1172. particle->direction *= (_maxVelocity / particle->direction.length());
  1173. }
  1174. // Update the position with the direction.
  1175. particle->position.add(particle->direction.x * scl.x * _particleSystemScaleVelocity * timeElapsed
  1176. , particle->direction.y * scl.y * _particleSystemScaleVelocity * timeElapsed
  1177. , particle->direction.z * scl.z * _particleSystemScaleVelocity * timeElapsed);
  1178. }
  1179. void PUParticleSystem3D::calulateRotationOffset( void )
  1180. {
  1181. if (_isMarkedForEmission)
  1182. {
  1183. // Use the uber particle system as centre of rotation and not the particle systems' own position.
  1184. _rotationCentre = _parentParticleSystem->getDerivedPosition();
  1185. }
  1186. else
  1187. {
  1188. // Use its own position
  1189. _rotationCentre = getDerivedPosition();
  1190. }
  1191. /** Use the derived orientation, which is the particle systems' own scenenode orientation,
  1192. or the orientation of the uber particle system, if this particle system is emitted itself.
  1193. */
  1194. Quaternion latestOrientationInverse = _latestOrientation;
  1195. latestOrientationInverse.inverse();
  1196. _rotationOffset = getDerivedOrientation() * latestOrientationInverse;
  1197. }
  1198. int PUParticleSystem3D::getAliveParticleCount() const
  1199. {
  1200. int sz = 0;
  1201. sz += _particlePool.getActiveDataList().size();
  1202. if (!_emittedEmitterParticlePool.empty()){
  1203. for (auto &iter : _emittedEmitterParticlePool){
  1204. sz += iter.second.getActiveDataList().size();
  1205. }
  1206. }
  1207. if (_emittedSystemParticlePool.empty())
  1208. return sz;
  1209. for (auto &iter : _emittedSystemParticlePool){
  1210. auto pool = iter.second;
  1211. sz += pool.getActiveDataList().size();
  1212. PUParticle3D *particle = static_cast<PUParticle3D *>(pool.getFirst());
  1213. while (particle)
  1214. {
  1215. sz += static_cast<PUParticleSystem3D*>(particle->particleEntityPtr)->getAliveParticleCount();
  1216. particle = static_cast<PUParticle3D *>(pool.getNext());
  1217. }
  1218. }
  1219. return sz;
  1220. }
  1221. void PUParticleSystem3D::forceStopParticleSystem()
  1222. {
  1223. if (_render)
  1224. _render->notifyStop();
  1225. for (auto &it : _observers){
  1226. it->notifyStop();
  1227. }
  1228. for (auto& it : _emitters) {
  1229. auto emitter = static_cast<PUEmitter*>(it);
  1230. emitter->notifyStop();
  1231. }
  1232. for (auto& it : _affectors) {
  1233. auto affector = static_cast<PUAffector*>(it);
  1234. affector->notifyStop();
  1235. }
  1236. unscheduleUpdate();
  1237. unPrepared();
  1238. }
  1239. NS_CC_END