ZMLParticleSystem.cpp 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181
  1. //
  2. // ZMLParticleSystem.cpp
  3. // Billiards
  4. //
  5. // Created by zhu on 2019/2/15.
  6. //
  7. #include "ZMLParticleSystem.h"
  8. #include "Curl.h"
  9. #include "vmath.hpp"
  10. //#include ""
  11. NS_RU_BEGIN
  12. class ZMLParticleSystemQuad;
  13. inline static float RANDOM_M11(unsigned int *seed) {
  14. *seed = *seed * 134775813 + 1;
  15. union {
  16. uint32_t d;
  17. float f;
  18. } u;
  19. u.d = (((uint32_t)(*seed) & 0x7fff) << 8) | 0x40000000;
  20. return u.f - 3.0f;
  21. }
  22. inline void normalize_point(float x, float y, particle_point* out)
  23. {
  24. float n = x * x + y * y;
  25. // Already normalized.
  26. if (n == 1.0f)
  27. return;
  28. n = sqrt(n);
  29. // Too close to zero.
  30. if (n < MATH_TOLERANCE)
  31. return;
  32. n = 1.0f / n;
  33. out->x = x * n;
  34. out->y = y * n;
  35. }
  36. ZMLParticleDataExpansion::ZMLParticleDataExpansion()
  37. {
  38. memset(this, 0, sizeof(ZMLParticleDataExpansion));
  39. }
  40. bool ZMLParticleDataExpansion::init(int count)
  41. {
  42. maxCount = count;
  43. startColorR = (float*)malloc(count * sizeof(float));
  44. startColorG = (float*)malloc(count * sizeof(float));
  45. startColorB = (float*)malloc(count * sizeof(float));
  46. startColorA = (float*)malloc(count * sizeof(float));
  47. deltaColorRAllLife = (float*)malloc(count * sizeof(float));
  48. deltaColorGAllLife = (float*)malloc(count * sizeof(float));
  49. deltaColorBAllLife = (float*)malloc(count * sizeof(float));
  50. deltaColorAAllLife = (float*)malloc(count * sizeof(float));
  51. sizeWidth = (float*)malloc(count * sizeof(float));
  52. startSizeWidth = (float*)malloc(count * sizeof(float));
  53. deltaSizeWidthAllLife = (float*)malloc(count * sizeof(float));
  54. sizeHeight = (float*)malloc(count * sizeof(float));
  55. startSizeHeighth = (float*)malloc(count * sizeof(float));
  56. deltaSizeHeightAllLife = (float*)malloc(count * sizeof(float));
  57. startRotation = (float*)malloc(count * sizeof(float));
  58. deltaRotationAllLife = (float*)malloc(count * sizeof(float));
  59. deltaLifePercentage = (float*)malloc(count * sizeof(float));
  60. lifePercentage = (float*)malloc(count * sizeof(float));
  61. textureIndex = (int*)malloc(count * sizeof(int));
  62. startTextureIndex = (int*)malloc(count * sizeof(int));
  63. posz = (float*)malloc(count * sizeof(float));
  64. maxSpeendZOffset = (float*)malloc(count * sizeof(float));
  65. life = (float*)malloc(count * sizeof(float));
  66. return startColorR && startColorG && startColorB && startColorA && deltaColorRAllLife && deltaColorGAllLife && deltaColorBAllLife && deltaColorAAllLife && sizeWidth && startSizeWidth && deltaSizeWidthAllLife && sizeHeight && startSizeHeighth && deltaSizeHeightAllLife && startRotation && deltaRotationAllLife && deltaLifePercentage && lifePercentage && textureIndex && startTextureIndex && posz && maxSpeendZOffset && life;
  67. }
  68. void ZMLParticleDataExpansion::release()
  69. {
  70. CC_SAFE_FREE(startColorR);
  71. CC_SAFE_FREE(startColorG);
  72. CC_SAFE_FREE(startColorB);
  73. CC_SAFE_FREE(startColorA);
  74. CC_SAFE_FREE(deltaColorRAllLife);
  75. CC_SAFE_FREE(deltaColorGAllLife);
  76. CC_SAFE_FREE(deltaColorBAllLife);
  77. CC_SAFE_FREE(deltaColorAAllLife);
  78. CC_SAFE_FREE(sizeWidth);
  79. CC_SAFE_FREE(startSizeWidth);
  80. CC_SAFE_FREE(deltaSizeWidthAllLife);
  81. CC_SAFE_FREE(sizeHeight);
  82. CC_SAFE_FREE(startSizeHeighth);
  83. CC_SAFE_FREE(deltaSizeHeightAllLife);
  84. CC_SAFE_FREE(startRotation);
  85. CC_SAFE_FREE(deltaRotationAllLife);
  86. CC_SAFE_FREE(deltaLifePercentage);
  87. CC_SAFE_FREE(lifePercentage);
  88. CC_SAFE_FREE(textureIndex);
  89. CC_SAFE_FREE(startTextureIndex);
  90. CC_SAFE_FREE(posz);
  91. CC_SAFE_FREE(maxSpeendZOffset);
  92. CC_SAFE_FREE(life);
  93. }
  94. ZMLParticleSystem::ZMLParticleSystem()
  95. : _oldPos(Vec2::ZERO)
  96. , _launcherangle(0)
  97. , _launcherV(0)
  98. , _texNumber(0)
  99. , _frameRate(-1)
  100. , _startSizeWidth(0)
  101. , _startSizeWidthVar(0)
  102. , _endSizeWidth(0)
  103. , _endSizeWidthVar(0)
  104. , _startSizeHeight(0)
  105. , _startSizeHeightVar(0)
  106. , _endSizeHeight(0)
  107. , _endSizeHeightVar(0)
  108. , _posZVar(0)
  109. , _maxWindX(0)
  110. , _maxWindY(0)
  111. , _windCycle(0)
  112. , _windTimelinePostion(0)
  113. , _winfTimelineDposPreS(0)
  114. , _lastAddParticleWordPostion(Vec2(-1,-1))
  115. ,_mainTexName("")
  116. ,_maskName("")
  117. ,_colorPower(1.0f)
  118. , _lockAspectRatio(false)
  119. , _aspectRatio(0)
  120. , _sizeWidthChangeLaw(nullptr)
  121. , _sizeHeightChangeLaw(nullptr)
  122. , _colorAChangeLaw(nullptr)
  123. , _spinChangeLaw(nullptr)
  124. , _speedXOffset(nullptr)
  125. , _speedYOffset(nullptr)
  126. , _speedZOffset(nullptr)
  127. , _windOffset(nullptr)
  128. {
  129. // CC_SAFE_FREE(_sizeChangeLaw);
  130. // CC_SAFE_FREE(_spinChangeLaw);
  131. // CC_SAFE_FREE(_colorAChangeLaw);
  132. modules.clear();
  133. }
  134. ZMLParticleSystem::~ZMLParticleSystem(){
  135. CC_SAFE_FREE(_sizeWidthChangeLaw);
  136. CC_SAFE_FREE(_sizeHeightChangeLaw);
  137. CC_SAFE_FREE(_spinChangeLaw);
  138. CC_SAFE_FREE(_colorAChangeLaw);
  139. CC_SAFE_FREE(_speedXOffset);
  140. CC_SAFE_FREE(_speedYOffset);
  141. CC_SAFE_FREE(_speedZOffset);
  142. CC_SAFE_FREE(_windOffset);
  143. _particleDataExpansion.release();
  144. auto iter = modules.begin();
  145. while(iter != modules.end())
  146. {
  147. delete iter->second;
  148. iter->second = nullptr;
  149. modules.erase(iter++);
  150. }
  151. }
  152. void ZMLParticleSystem::addModule(ParticleSystemModule* module)
  153. {
  154. ParticleSystemModuleFlag flag = module->getFlag();
  155. if (modules.find(flag) != modules.end())
  156. return;
  157. module->setParticleSystem(this);
  158. modules.insert(pair<ParticleSystemModuleFlag,ParticleSystemModule*>(module->getFlag(),module));
  159. }
  160. ParticleSystemModule* ZMLParticleSystem::getModule(ParticleSystemModuleFlag flag)
  161. {
  162. auto iter = modules.find(flag);
  163. if (iter == modules.end() ) {
  164. return nullptr;
  165. }
  166. return iter->second;
  167. }
  168. void ZMLParticleSystem::SetColorPower(float colorPower)
  169. {
  170. _colorPower = colorPower;
  171. getGLProgramState()->setUniformFloat("color_power", colorPower);
  172. }
  173. ZMLParticleSystem* ZMLParticleSystem::createWithJsonString(string jsonStr){
  174. ZMLParticleSystem *ret = new (std::nothrow) ZMLParticleSystem();
  175. if (ret && ret->initWithJsonString(jsonStr))
  176. {
  177. ret->autorelease();
  178. return ret;
  179. }
  180. CC_SAFE_DELETE(ret);
  181. return ret;
  182. }
  183. ZMLParticleSystem* ZMLParticleSystem::createWithJsonFile(string path){
  184. ZMLParticleSystem *ret = new (std::nothrow) ZMLParticleSystem();
  185. if (ret && ret->initWithJsonFile(path))
  186. {
  187. ret->autorelease();
  188. return ret;
  189. }
  190. CC_SAFE_DELETE(ret);
  191. return ret;
  192. }
  193. //static std::map<string, string> s_mapJson;
  194. bool ZMLParticleSystem::initWithJsonFile(string path){
  195. string cfg;
  196. static std::map<string, string> s_mapJson;
  197. if (s_mapJson.find(path) != s_mapJson.end())
  198. {
  199. cfg = s_mapJson.find(path)->second;
  200. }else {
  201. Data datas = FileUtils::getInstance()->getDataFromFile(path);
  202. unsigned char* data = datas.getBytes();
  203. ssize_t len = datas.getSize();
  204. string err = "";
  205. cfg = string(data,data+len);
  206. s_mapJson.insert(pair<string, string>(path,cfg));
  207. if(err != ""){
  208. return false;
  209. }
  210. }
  211. return initWithJsonString(cfg);
  212. }
  213. bool ZMLParticleSystem::initWithJsonString(string jsonStr){
  214. bool ret = false;
  215. string err = "";
  216. Json rootjson = Json::parse(jsonStr, err);
  217. if (err != ""){
  218. return false;
  219. }
  220. do
  221. {
  222. int maxParticles = rootjson["maxParticles"].int_value();
  223. _mainTexName = rootjson["mainTexture"].string_value();
  224. _maskName = rootjson["alphaTexture"].string_value();
  225. _colorPower = rootjson["colorPower"].number_value();
  226. _shaderType = rootjson["shaderType"].int_value();
  227. _particleDataExpansion.release();
  228. if( !_particleDataExpansion.init(maxParticles))
  229. {
  230. CCLOG("Particle system: not enough memory");
  231. this->release();
  232. return false;
  233. }
  234. // _particleCount = 0;
  235. // self, not super
  236. if(this->initWithTotalParticles(maxParticles))
  237. {
  238. // Emitter name in particle designer 2.0
  239. // _configName = dictionary["configName"].asString();
  240. // angle
  241. _angle = rootjson["angle"].number_value();
  242. _angleVar = rootjson["angleVariance"].number_value();
  243. _angleEven = rootjson["angleEvenDist"].bool_value();
  244. // duration
  245. _duration = rootjson["duration"].number_value();
  246. _explosiveness_ratio = rootjson["explosiveness_ratio"].number_value();
  247. // blend function
  248. {
  249. //TODO: 叠加模式
  250. _blendFunc.src = rootjson["blendFuncSource"].number_value();
  251. _blendFunc.dst = rootjson["blendFuncDestination"].number_value();
  252. }
  253. switch (rootjson["positionType"].int_value()) {
  254. case 0:
  255. _positionType = ParticleSystem::PositionType::FREE;
  256. break;
  257. case 1:
  258. _positionType = ParticleSystem::PositionType::RELATIVE;
  259. break;
  260. case 2:
  261. _positionType = ParticleSystem::PositionType::GROUPED;
  262. break;
  263. default:
  264. _positionType = ParticleSystem::PositionType::FREE;
  265. break;
  266. }
  267. // color
  268. _startColor.a = rootjson["startColorAlpha"].number_value();
  269. _startColor.b = rootjson["startColorBlue"].number_value();
  270. _startColor.g = rootjson["startColorGreen"].number_value();
  271. _startColor.r = rootjson["startColorRed"].number_value();
  272. _startColorVar.a = rootjson["startColorVarianceAlpha"].number_value();
  273. _startColorVar.b = rootjson["startColorVarianceBlue"].number_value();
  274. _startColorVar.g = rootjson["startColorVarianceGreen"].number_value();
  275. _startColorVar.r = rootjson["startColorVarianceRed"].number_value();
  276. _endColor.a = rootjson["finishColorAlpha"].number_value();
  277. _endColor.b = rootjson["finishColorBlue"].number_value();
  278. _endColor.g = rootjson["finishColorGreen"].number_value();
  279. _endColor.r = rootjson["finishColorRed"].number_value();
  280. _endColorVar.a = rootjson["finishColorVarianceAlpha"].number_value();
  281. _endColorVar.b = rootjson["finishColorVarianceBlue"].number_value();
  282. _endColorVar.g = rootjson["finishColorVarianceGreen"].number_value();
  283. _endColorVar.r = rootjson["finishColorVarianceRed"].number_value();
  284. // particle size
  285. _startSizeWidth = rootjson["startParticleSizeWidth"].number_value();
  286. _startSizeWidthVar = rootjson["startParticleSizeWidthVariance"].number_value();
  287. _endSizeWidth = rootjson["finishParticleSizeWidth"].number_value();
  288. _endSizeWidthVar = rootjson["finishParticleSizeWidthVariance"].number_value();
  289. _lockAspectRatio = rootjson["lockAspectRatio"].bool_value();
  290. _startSizeHeight = rootjson["startParticleSizeHeight"].number_value();
  291. if(_lockAspectRatio){
  292. if(_startSizeWidth != 0){
  293. _aspectRatio = _startSizeHeight / _startSizeWidth;
  294. } else {
  295. _aspectRatio = 1;
  296. }
  297. }
  298. _startSizeHeightVar = rootjson["startParticleSizeHeightVariance"].number_value();
  299. _endSizeHeight = rootjson["finishParticleSizeHeight"].number_value();
  300. _endSizeHeightVar = rootjson["finishParticleSizeHeightVariance"].number_value();
  301. // position 不用在这搞
  302. // float x = dictionary["sourcePositionx"].asFloat();
  303. // float y = dictionary["sourcePositiony"].asFloat();
  304. _posVar.x = rootjson["sourcePositionVariancex"].number_value();
  305. _posVar.y = rootjson["sourcePositionVariancey"].number_value();
  306. _posZVar = rootjson["sourcePositionVariancez"].number_value();
  307. // Spinning
  308. _startSpin = rootjson["rotationStart"].number_value();
  309. _startSpinVar = rootjson["rotationStartVariance"].number_value();
  310. _endSpin = rootjson["rotationEnd"].number_value();
  311. _endSpinVar = rootjson["rotationEndVariance"].number_value();
  312. _frameRate = rootjson["frameRate"].int_value();
  313. // life span
  314. _life = rootjson["particleLifespan"].number_value();
  315. _lifeVar = rootjson["particleLifespanVariance"].number_value();
  316. // emission Rate
  317. _emissionRate = _totalParticles / _life * 0.85;
  318. // _emitCounter = MAX(1, _emissionRate / 60);
  319. Json::array sizeWidthChangeLaw = rootjson["sizeWidthChangeLaw"].array_items();
  320. _sizeWidthChangeLaw = (float*)malloc(sizeWidthChangeLaw.size() * sizeof(float));
  321. for(int i = 0; i < sizeWidthChangeLaw.size(); i++){
  322. _sizeWidthChangeLaw[i] = sizeWidthChangeLaw.at(i).number_value();
  323. }
  324. Json::array sizeHeightChangeLa = rootjson["sizeHeightChangeLaw"].array_items();
  325. _sizeHeightChangeLaw = (float*)malloc(sizeHeightChangeLa.size() * sizeof(float));
  326. for(int i = 0; i < sizeHeightChangeLa.size(); i++){
  327. _sizeHeightChangeLaw[i] = sizeHeightChangeLa.at(i).number_value();
  328. }
  329. Json::array spinChangeLaw = rootjson["spinChangeLaw"].array_items();
  330. _spinChangeLaw = (float*)malloc(spinChangeLaw.size() * sizeof(float));
  331. for(int i = 0; i < spinChangeLaw.size(); i++){
  332. _spinChangeLaw[i] = spinChangeLaw.at(i).number_value();
  333. }
  334. Json::array colorAChangeLaw = rootjson["colorAChangeLaw"].array_items();
  335. _colorAChangeLaw = (float*)malloc(colorAChangeLaw.size() * sizeof(float));
  336. for(int i = 0; i < colorAChangeLaw.size(); i++){
  337. _colorAChangeLaw[i] = colorAChangeLaw.at(i).number_value();
  338. }
  339. _emitterMode = (Mode)rootjson["emitterMode"].int_value();
  340. // Mode A: Gravity + tangential accel + radial accel
  341. if(_emitterMode == Mode::GRAVITY)
  342. {
  343. // gravity
  344. modeA.gravity.x = rootjson["gravityx"].number_value();
  345. modeA.gravity.y = rootjson["gravityy"].number_value();
  346. // speed
  347. modeA.speed = rootjson["speed"].number_value();
  348. modeA.speedVar = rootjson["speedVariance"].number_value();
  349. // radial acceleration
  350. modeA.radialAccel = rootjson["radialAcceleration"].number_value();
  351. modeA.radialAccelVar = rootjson["radialAccelVariance"].number_value();
  352. // tangential acceleration
  353. modeA.tangentialAccel = rootjson["tangentialAcceleration"].number_value();
  354. modeA.tangentialAccelVar = rootjson["tangentialAccelVariance"].number_value();
  355. // rotation is dir
  356. modeA.rotationIsDir = rootjson["rotationIsDir"].bool_value();
  357. // 速度
  358. Json::array speedXOffset = rootjson["speedXOffset"].array_items();
  359. _speedXOffset = (float*)malloc(speedXOffset.size() * sizeof(float));
  360. for(int i = 0; i < speedXOffset.size(); i++){
  361. _speedXOffset[i] = speedXOffset.at(i).number_value();
  362. }
  363. Json::array speedYOffset = rootjson["speedYOffset"].array_items();
  364. _speedYOffset = (float*)malloc(speedYOffset.size() * sizeof(float));
  365. for(int i = 0; i < speedYOffset.size(); i++){
  366. _speedYOffset[i] = speedYOffset.at(i).number_value();
  367. }
  368. _maxSpeendZOffset = rootjson["maxSpeendZOffset"].number_value();
  369. Json::array speedZOffset = rootjson["speedZOffset"].array_items();
  370. _speedZOffset = (float*)malloc(speedZOffset.size() * sizeof(float));
  371. for(int i = 0; i < speedZOffset.size(); i++){
  372. _speedZOffset[i] = speedZOffset.at(i).number_value();
  373. }
  374. // 风速有关
  375. _maxWindX = rootjson["maxWindX"].number_value();
  376. _maxWindY = rootjson["maxWindY"].number_value();
  377. _windCycle = rootjson["windCycle"].number_value();
  378. Json::array windOffset = rootjson["windOffset"].array_items();
  379. _windOffset = (float*)malloc(windOffset.size() * sizeof(float));
  380. for(int i = 0; i < windOffset.size(); i++){
  381. _windOffset[i] = windOffset.at(i).number_value();
  382. }
  383. if(_windCycle == 0){
  384. _windCycle = 1;
  385. }
  386. _winfTimelineDposPreS = 100 / _windCycle;
  387. _windTimelinePostion = 0;
  388. }
  389. else
  390. {
  391. modeA.rotationIsDir = rootjson["rotationIsDir"].bool_value();
  392. modeB.startRadius = rootjson["startRadius"].number_value();
  393. modeB.startRadiusVar = rootjson["startRadiusVar"].number_value();
  394. modeB.endRadius = rootjson["endRadius"].number_value();
  395. modeB.endRadiusVar = rootjson["endRadiusVar"].number_value();
  396. modeB.rotatePerSecond = rootjson["rotatePerSecond"].number_value();
  397. modeB.rotatePerSecondVar = rootjson["rotatePerSecondVar"].number_value();
  398. }
  399. bool bBigPic = false;//判断粒子图片是否在plist大图中 在 则为true
  400. Texture2D* mainTex = nullptr;
  401. if (_mainTexName.length() > 0)
  402. {
  403. #if PARTICLE_EDITOR_MODE
  404. string path = rootjson["editorTexturePath"].string_value();
  405. mainTex = Director::getInstance()->getTextureCache()->addImage(path);
  406. #else
  407. if (FileUtils::getInstance()->fullPathForFilename(_mainTexName).size() == 0){//在plist大图中查找图片
  408. SpriteFrame* frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(_mainTexName);
  409. mainTex = frame->getTexture();
  410. bBigPic = true;
  411. } else {
  412. mainTex = Director::getInstance()->getTextureCache()->addImage(_mainTexName);
  413. }
  414. #endif
  415. }
  416. moduleFlag = rootjson["moduleFlag"].int_value();
  417. if ((moduleFlag & (int)ParticleSystemModuleFlag::TEXTURE_SHEET) != 0)
  418. {
  419. int tileX = rootjson["tileX"].int_value();
  420. int tileY = rootjson["tileY"].int_value();
  421. int startFrame = rootjson["startFrame"].int_value();
  422. int frameCount = rootjson["frameCount"].int_value();
  423. int sheetCycles = rootjson["sheetCycles"].int_value();
  424. int flipTileY = rootjson["flipTileY"].int_value();
  425. bool useRandomStartFrame = rootjson["useRandomStartFrame"].bool_value();
  426. auto module = new TextureSheetAnimationModule();
  427. module->setTiles(Vec2(tileX,tileY));
  428. module->setStartFrame(startFrame);
  429. module->setFrameCount(frameCount);
  430. module->setFlipY(flipTileY);
  431. module->setCycles(sheetCycles);
  432. module->setUseRandomStartFrame(useRandomStartFrame);
  433. if (bBigPic) {
  434. module->setFileName(_mainTexName);
  435. }
  436. if (mainTex)
  437. {
  438. module->setTexture(mainTex);
  439. }
  440. addModule(module);
  441. }
  442. if ((moduleFlag & (int)ParticleSystemModuleFlag::NOISE) != 0)
  443. {
  444. auto module = new NoiseModule();
  445. float _frequency = rootjson["noise_frequency"].number_value();
  446. int _octaves = rootjson["noise_octaves"].int_value();
  447. float _lacunarity = rootjson["noise_lacunarity"].number_value();
  448. float _persistence = rootjson["noise_persistence"].number_value();
  449. float _strength = rootjson["noise_strength"].number_value();
  450. module->setFrequency(_frequency);
  451. module->setOctaves(_octaves);
  452. module->setLacunarity(_lacunarity);
  453. module->setPersistence(_persistence);
  454. module->setStrength(_strength);
  455. //TODO
  456. addModule(module);
  457. }
  458. auto iter = modules.begin();
  459. while(iter != modules.end())
  460. {
  461. ParticleSystemModule* module = iter->second;
  462. module->setEnable(true);
  463. iter++;
  464. }
  465. ret = true;
  466. }
  467. } while (0);
  468. // free(buffer);
  469. // free(deflated);
  470. return ret;
  471. }
  472. void ZMLParticleSystem::addParticles(int count){
  473. if (_paused)
  474. return;
  475. uint32_t RANDSEED = rand();
  476. int start = _particleCount;
  477. _particleCount += count;
  478. //life
  479. for (int i = start; i < _particleCount ; ++i)
  480. {
  481. float theLife = _life + _lifeVar * RANDOM_M11(&RANDSEED);
  482. _particleData.timeToLive[i] = MAX(0, theLife);
  483. _particleDataExpansion.life[i] = _particleData.timeToLive[i];
  484. _particleDataExpansion.lifePercentage[i] = 0;
  485. _particleDataExpansion.deltaLifePercentage[i] = 100 / _particleDataExpansion.life[i] ;
  486. }
  487. TextureSheetAnimationModule * module = dynamic_cast<TextureSheetAnimationModule*>(getModule(ParticleSystemModuleFlag::TEXTURE_SHEET));
  488. //(TextureSheetAnimationModule*)getModule(ParticleSystemModuleFlag::TEXTURE_SHEET);
  489. for(int i = start; i < _particleCount ; ++i){
  490. int index = (module != nullptr && !module->isUseRandomStartFrame()) ? 0 : (int)_texNumber * abs(RANDOM_M11(&RANDSEED));
  491. _particleDataExpansion.textureIndex[i] = index;
  492. _particleDataExpansion.startTextureIndex[i] = _particleDataExpansion.textureIndex[i] ;
  493. // CCLOG("_particleDataExpansion.texIndex[i] is %d",_particleDataExpansion.textureIndex[i]);
  494. }
  495. //position
  496. for (int i = start; i < _particleCount; ++i)
  497. {
  498. _particleData.posx[i] = _sourcePosition.x + _posVar.x * RANDOM_M11(&RANDSEED);
  499. }
  500. for (int i = start; i < _particleCount; ++i)
  501. {
  502. _particleData.posy[i] = _sourcePosition.y + _posVar.y * RANDOM_M11(&RANDSEED);
  503. }
  504. for (int i = start; i < _particleCount; ++i)
  505. {
  506. _particleDataExpansion.posz[i] = _posZVar * RANDOM_M11(&RANDSEED);
  507. _particleDataExpansion.maxSpeendZOffset[i] = _maxSpeendZOffset * RANDOM_M11(&RANDSEED);
  508. }
  509. //color
  510. #define SET_COLOR(c, b, v)\
  511. for (int i = start; i < _particleCount; ++i)\
  512. {\
  513. c[i] = clampf( b + v * RANDOM_M11(&RANDSEED) , 0 , 1 );\
  514. }
  515. SET_COLOR(_particleData.colorR, _startColor.r, _startColorVar.r);
  516. SET_COLOR(_particleData.colorG, _startColor.g, _startColorVar.g);
  517. SET_COLOR(_particleData.colorB, _startColor.b, _startColorVar.b);
  518. SET_COLOR(_particleData.colorA, _startColor.a, _startColorVar.a);
  519. SET_COLOR(_particleData.deltaColorR, _endColor.r, _endColorVar.r);
  520. SET_COLOR(_particleData.deltaColorG, _endColor.g, _endColorVar.g);
  521. SET_COLOR(_particleData.deltaColorB, _endColor.b, _endColorVar.b);
  522. SET_COLOR(_particleData.deltaColorA, _endColor.a, _endColorVar.a);
  523. #define SET_DELTA_COLOR_AllLife(sc, dca, c, dc)\
  524. for (int i = start; i < _particleCount; ++i)\
  525. {\
  526. sc[i] = c[i];\
  527. dca[i] = dc[i] - c[i];\
  528. }
  529. SET_DELTA_COLOR_AllLife(_particleDataExpansion.startColorR, _particleDataExpansion.deltaColorRAllLife,_particleData.colorR, _particleData.deltaColorR);
  530. SET_DELTA_COLOR_AllLife(_particleDataExpansion.startColorG, _particleDataExpansion.deltaColorGAllLife,_particleData.colorG, _particleData.deltaColorG);
  531. SET_DELTA_COLOR_AllLife(_particleDataExpansion.startColorB, _particleDataExpansion.deltaColorBAllLife,_particleData.colorG, _particleData.deltaColorB);
  532. SET_DELTA_COLOR_AllLife(_particleDataExpansion.startColorA, _particleDataExpansion.deltaColorAAllLife,_particleData.colorA, _particleData.deltaColorA);
  533. #define SET_DELTA_COLOR(c, dc)\
  534. for (int i = start; i < _particleCount; ++i)\
  535. {\
  536. dc[i] = (dc[i] - c[i]) / _particleData.timeToLive[i];\
  537. }
  538. SET_DELTA_COLOR(_particleData.colorR, _particleData.deltaColorR);
  539. SET_DELTA_COLOR(_particleData.colorG, _particleData.deltaColorG);
  540. SET_DELTA_COLOR(_particleData.colorB, _particleData.deltaColorB);
  541. SET_DELTA_COLOR(_particleData.colorA, _particleData.deltaColorA);
  542. //size
  543. for (int i = start; i < _particleCount; ++i)
  544. {
  545. _particleDataExpansion.sizeWidth[i] = _startSizeWidth + _startSizeWidthVar * RANDOM_M11(&RANDSEED);
  546. _particleDataExpansion.sizeWidth[i] = MAX(0, _particleDataExpansion.sizeWidth[i]);
  547. _particleDataExpansion.startSizeWidth[i] = _particleDataExpansion.sizeWidth[i];
  548. _particleDataExpansion.sizeHeight[i] = _startSizeHeight + _startSizeHeightVar * RANDOM_M11(&RANDSEED);
  549. _particleDataExpansion.sizeHeight[i] = MAX(0, _particleDataExpansion.sizeHeight[i]);
  550. _particleDataExpansion.startSizeHeighth[i] = _particleDataExpansion.sizeHeight[i];
  551. }
  552. if (_endSizeWidth != START_SIZE_EQUAL_TO_END_SIZE)
  553. {
  554. for (int i = start; i < _particleCount; ++i)
  555. {
  556. float endSizeWidth = _endSizeWidth + _endSizeWidthVar * RANDOM_M11(&RANDSEED);
  557. endSizeWidth = MAX(0, endSizeWidth);
  558. _particleDataExpansion.deltaSizeWidthAllLife[i] = endSizeWidth - _particleDataExpansion.startSizeWidth[i];
  559. }
  560. }
  561. else
  562. {
  563. for (int i = start; i < _particleCount; ++i)
  564. {
  565. float deltaSizeWidth = _endSizeWidthVar * RANDOM_M11(&RANDSEED);
  566. (_particleDataExpansion.startSizeWidth[i] + deltaSizeWidth) < 0 ? _particleDataExpansion.deltaSizeWidthAllLife[i] = -_particleDataExpansion.startSizeWidth[i] : _particleDataExpansion.deltaSizeWidthAllLife[i] = deltaSizeWidth;
  567. }
  568. }
  569. if (_endSizeHeight != START_SIZE_EQUAL_TO_END_SIZE) {
  570. for (int i = start; i < _particleCount; ++i)
  571. {
  572. float endSizeHeigh = _endSizeHeight + _endSizeHeightVar * RANDOM_M11(&RANDSEED);
  573. endSizeHeigh = MAX(0, endSizeHeigh);
  574. _particleDataExpansion.deltaSizeHeightAllLife[i] = endSizeHeigh - _particleDataExpansion.startSizeHeighth[i];
  575. }
  576. }else {
  577. for (int i = start; i < _particleCount; ++i)
  578. {
  579. float deltaSizeHeigh = _endSizeHeightVar * RANDOM_M11(&RANDSEED);
  580. (_particleDataExpansion.startSizeHeighth[i] + deltaSizeHeigh) < 0 ? _particleDataExpansion.deltaSizeHeightAllLife[i] = -_particleDataExpansion.startSizeHeighth[i] : _particleDataExpansion.deltaSizeHeightAllLife[i] = deltaSizeHeigh;
  581. }
  582. }
  583. // rotation
  584. for (int i = start; i < _particleCount; ++i)
  585. {
  586. _particleData.rotation[i] = _startSpin + _startSpinVar * RANDOM_M11(&RANDSEED);
  587. _particleDataExpansion.startRotation[i] = _particleData.rotation[i];
  588. }
  589. if(_endSpin != START_ROTATION_EQUAL_TO_END_ROTATION){
  590. for (int i = start; i < _particleCount; ++i)
  591. {
  592. float endA = _endSpin + _endSpinVar * RANDOM_M11(&RANDSEED);
  593. _particleDataExpansion.deltaRotationAllLife[i] = endA - _particleData.rotation[i];
  594. }
  595. } else {
  596. // 结束旋转在初始角度基础上
  597. for (int i = start; i < _particleCount; ++i)
  598. {
  599. _particleDataExpansion.deltaRotationAllLife[i] = _endSpinVar * RANDOM_M11(&RANDSEED);
  600. }
  601. }
  602. // position
  603. Vec2 pos;
  604. Vec2 changePos;
  605. if (_positionType == PositionType::FREE)
  606. {
  607. if(_lastAddParticleWordPostion != Vec2(-1,-1)){
  608. pos = this->convertToWorldSpace(Vec2::ZERO);
  609. changePos = pos - _lastAddParticleWordPostion;
  610. _lastAddParticleWordPostion = pos;
  611. } else {
  612. pos = this->convertToWorldSpace(Vec2::ZERO);
  613. _lastAddParticleWordPostion = pos;
  614. }
  615. }
  616. else if (_positionType == PositionType::RELATIVE)
  617. {
  618. pos = _position;
  619. }
  620. float v = 1.0 / count;
  621. for (int i = start; i < _particleCount; ++i)
  622. {
  623. // count;//新加的粒子数
  624. _particleData.startPosX[i] = pos.x - changePos.x * v * (i - start);
  625. // _particleData.startPosX[i] = pos.x;
  626. }
  627. for (int i = start; i < _particleCount; ++i)
  628. {
  629. _particleData.startPosY[i] = pos.y - changePos.y * v * (i - start);
  630. // _particleData.startPosY[i] = pos.y;
  631. }
  632. // Mode Gravity: A
  633. if (_emitterMode == Mode::GRAVITY)
  634. {
  635. // radial accel
  636. for (int i = start; i < _particleCount; ++i)
  637. {
  638. _particleData.modeA.radialAccel[i] = modeA.radialAccel + modeA.radialAccelVar * RANDOM_M11(&RANDSEED);
  639. }
  640. // tangential accel
  641. for (int i = start; i < _particleCount; ++i)
  642. {
  643. _particleData.modeA.tangentialAccel[i] = modeA.tangentialAccel + modeA.tangentialAccelVar * RANDOM_M11(&RANDSEED);
  644. }
  645. // rotation is dir
  646. if( modeA.rotationIsDir )
  647. {
  648. for (int i = start; i < _particleCount; ++i)
  649. {
  650. float a = CC_DEGREES_TO_RADIANS( _angle + _angleVar * RANDOM_M11(&RANDSEED) );
  651. Vec2 v(cosf( a ), sinf( a ));
  652. float s = modeA.speed + modeA.speedVar * RANDOM_M11(&RANDSEED);
  653. Vec2 dir = v * s;
  654. _particleData.modeA.dirX[i] = dir.x;//v * s ;
  655. _particleData.modeA.dirY[i] = dir.y;
  656. _particleData.rotation[i] = -CC_RADIANS_TO_DEGREES(dir.getAngle()) + _startSpin + _startSpinVar * RANDOM_M11(&RANDSEED);;
  657. _particleDataExpansion.startRotation[i] = _particleData.rotation[i];
  658. }
  659. }
  660. else{
  661. for (int i = start; i < _particleCount; ++i) {
  662. float a = 0;
  663. if (_angleEven) {
  664. float angleStep = _angleVar / _particleCount;
  665. a = CC_DEGREES_TO_RADIANS( _angle + angleStep * i + 10*RANDOM_M11(&RANDSEED));
  666. } else {
  667. a = CC_DEGREES_TO_RADIANS( _angle + _angleVar * RANDOM_M11(&RANDSEED));
  668. }
  669. Vec2 v(cosf( a ), sinf( a ));
  670. float s = modeA.speed + modeA.speedVar * RANDOM_M11(&RANDSEED);
  671. Vec2 dir = v * s;
  672. _particleData.modeA.dirX[i] = dir.x;//v * s ;
  673. _particleData.modeA.dirY[i] = dir.y;
  674. }
  675. }
  676. }
  677. // Mode Radius: B
  678. else
  679. {
  680. //Need to check by Jacky
  681. // Set the default diameter of the particle from the source position
  682. for (int i = start; i < _particleCount; ++i)
  683. {
  684. _particleData.modeB.radius[i] = modeB.startRadius + modeB.startRadiusVar * RANDOM_M11(&RANDSEED);
  685. }
  686. for (int i = start; i < _particleCount; ++i)
  687. {
  688. float a = 0;
  689. if (_angleEven) {
  690. float angleStep = _angleVar / _particleCount;
  691. a = CC_DEGREES_TO_RADIANS( _angle + angleStep * i + 10*RANDOM_M11(&RANDSEED));
  692. } else {
  693. a = CC_DEGREES_TO_RADIANS( _angle + _angleVar * RANDOM_M11(&RANDSEED));
  694. }
  695. _particleData.modeB.angle[i] = a;
  696. }
  697. for (int i = start; i < _particleCount; ++i)
  698. {
  699. _particleData.modeB.degreesPerSecond[i] = CC_DEGREES_TO_RADIANS(modeB.rotatePerSecond + modeB.rotatePerSecondVar * RANDOM_M11(&RANDSEED));
  700. }
  701. if(modeB.endRadius == START_RADIUS_EQUAL_TO_END_RADIUS)
  702. {
  703. for (int i = start; i < _particleCount; ++i)
  704. {
  705. _particleData.modeB.deltaRadius[i] = 0.0f;
  706. }
  707. }
  708. else
  709. {
  710. for (int i = start; i < _particleCount; ++i)
  711. {
  712. float endRadius = modeB.endRadius + modeB.endRadiusVar * RANDOM_M11(&RANDSEED);
  713. _particleData.modeB.deltaRadius[i] = (endRadius - _particleData.modeB.radius[i]) / _particleData.timeToLive[i];
  714. }
  715. }
  716. }
  717. }
  718. void ZMLParticleSystem::update(float dt){
  719. CC_PROFILER_START_CATEGORY(kProfilerCategoryParticles , "ZMLParticleSystem - update");
  720. if (_isActive && _emissionRate)
  721. {
  722. if (_oldPos != getPosition()){
  723. // _launcherangle = (getPosition() - _oldPos).getAngle();
  724. _launcherV = (getPosition() - _oldPos).getLength() / dt * 0.5;
  725. _launcherV = 5;
  726. } else {
  727. _launcherangle = 0;
  728. _launcherV = 0;
  729. }
  730. _oldPos = getPosition();
  731. _windTimelinePostion += _winfTimelineDposPreS * dt;
  732. float rate = 1.0f / _emissionRate;
  733. int totalParticles = static_cast<int>(_totalParticles * __totalParticleCountFactor);
  734. // {
  735. _emitCounter += dt;
  736. if (_emitCounter < 0.f)
  737. _emitCounter = 0.f;
  738. // }
  739. int emitCount = MIN(totalParticles - _particleCount, _emitCounter * _emissionRate);
  740. if( _explosiveness_ratio > (0.0 + FLT_EPSILON))
  741. {
  742. int explosiveCount = (int)(_explosiveness_ratio * totalParticles);
  743. //目前只在开始时爆发一次
  744. if (_elapsed < 0.0f + FLT_EPSILON)
  745. {
  746. addParticles(explosiveCount);
  747. CCLOG("emitCount :%d %d %f,%f",_particleCount,emitCount ,_emitCounter,_emissionRate);
  748. }
  749. }else {
  750. addParticles(emitCount);
  751. }
  752. _emitCounter -= rate *emitCount;
  753. _elapsed += dt;
  754. if (_elapsed < 0.f)
  755. _elapsed = 0.f;
  756. if (_duration != DURATION_INFINITY && _duration < _elapsed)
  757. {
  758. CCLOG("stop particle : %f %f",_duration,_elapsed);
  759. this->stopSystem();
  760. }
  761. }
  762. for (int i = 0; i < _particleCount; ++i)
  763. {
  764. _particleData.timeToLive[i] -= dt;
  765. _particleDataExpansion.lifePercentage[i] += _particleDataExpansion.deltaLifePercentage[i] * dt;
  766. _particleDataExpansion.lifePercentage[i] = MAX(0, MIN(_particleDataExpansion.lifePercentage[i], 100));
  767. }
  768. for (int i = 0; i < _particleCount; ++i)
  769. {
  770. if (_particleData.timeToLive[i] <= 0.0f)
  771. {
  772. int j = _particleCount - 1;
  773. while (j > 0 && _particleData.timeToLive[j] <= 0)
  774. {
  775. _particleCount--;
  776. j--;
  777. }
  778. _particleData.copyParticle(i, _particleCount - 1);
  779. _particleDataExpansion.copyParticle(i, _particleCount - 1);
  780. if (_batchNode)
  781. {
  782. //disable the switched particle
  783. int currentIndex = _particleData.atlasIndex[i];
  784. _batchNode->disableParticle(_atlasIndex + currentIndex);
  785. //switch indexes
  786. _particleData.atlasIndex[_particleCount - 1] = currentIndex;
  787. }
  788. --_particleCount;
  789. if( _particleCount == 0 && _isAutoRemoveOnFinish )
  790. {
  791. this->unscheduleUpdate();
  792. _parent->removeChild(this, true);
  793. return;
  794. }
  795. }
  796. }
  797. if (_emitterMode == Mode::GRAVITY)
  798. {
  799. int windIndex = ((int)_windTimelinePostion) % 101;
  800. float windPercentage = _windOffset[windIndex];
  801. float windX = _maxWindX * windPercentage;
  802. float windY = _maxWindY * windPercentage;
  803. for (int i = 0 ; i < _particleCount; ++i)
  804. {
  805. particle_point tmp, radial = {0.0f, 0.0f}, tangential;
  806. // radial acceleration
  807. if (_particleData.posx[i] || _particleData.posy[i])
  808. {
  809. normalize_point(_particleData.posx[i], _particleData.posy[i], &radial);
  810. }
  811. tangential = radial;
  812. radial.x *= _particleData.modeA.radialAccel[i];
  813. radial.y *= _particleData.modeA.radialAccel[i];
  814. // tangential acceleration
  815. std::swap(tangential.x, tangential.y);
  816. tangential.x *= - _particleData.modeA.tangentialAccel[i];
  817. tangential.y *= _particleData.modeA.tangentialAccel[i];
  818. // (gravity + radial + tangential + wind) * dt
  819. tmp.x = radial.x + tangential.x + modeA.gravity.x + windX;
  820. tmp.y = radial.y + tangential.y + modeA.gravity.y + windY;
  821. tmp.x *= dt;
  822. tmp.y *= dt;
  823. _particleData.modeA.dirX[i] += tmp.x;
  824. _particleData.modeA.dirY[i] += tmp.y;
  825. // this is cocos2d-x v3.0
  826. // if (_configName.length()>0 && _yCoordFlipped != -1)
  827. // this is cocos2d-x v3.0
  828. tmp.x = _particleData.modeA.dirX[i] * dt * _yCoordFlipped;
  829. tmp.y = _particleData.modeA.dirY[i] * dt * _yCoordFlipped;
  830. _particleData.posx[i] += tmp.x;
  831. _particleData.posy[i] += tmp.y;
  832. int index = _particleDataExpansion.lifePercentage[i];
  833. float speendXOffset = _speedXOffset[index];
  834. float speendYOffset = _speedYOffset[index];
  835. float speendZOffset = _speedZOffset[index];
  836. CurlNoise::Vector3 noise = CurlNoise::Vector3(0,0,0);
  837. NoiseModule* module = dynamic_cast<NoiseModule*>(getModule(ParticleSystemModuleFlag::NOISE));
  838. if (module != nullptr)
  839. {
  840. CurlNoise::CurlSettings setting;
  841. setting.m_bCheapGradient = true;
  842. setting.m_Frequency = module->getFrequency();
  843. setting.m_NumOctaves = module->getOctaves();
  844. setting.m_Lacunarity = module->getLacunarity();
  845. setting.m_Persistence = module->getPersistence();
  846. CurlNoise::SetCurlSettings(setting);
  847. noise = CurlNoise::ComputeCurlWithoutObstacles(CurlNoise::Vector3(_particleData.posx[i],_particleData.posy[i],0));
  848. noise *= module->getStrength();
  849. }
  850. _particleData.posx[i] += (speendXOffset * dt) + noise.getX() ;
  851. _particleData.posy[i] += (speendYOffset * dt) + noise.getY() ;
  852. _particleDataExpansion.posz[i] += (speendZOffset*_particleDataExpansion.maxSpeendZOffset[i] * dt);
  853. }
  854. }
  855. else
  856. {
  857. //Why use so many for-loop separately instead of putting them together?
  858. //When the processor needs to read from or write to a location in memory,
  859. //it first checks whether a copy of that data is in the cache.
  860. //And every property's memory of the particle system is continuous,
  861. //for the purpose of improving cache hit rate, we should process only one property in one for-loop AFAP.
  862. //It was proved to be effective especially for low-end machine.
  863. for (int i = 0; i < _particleCount; ++i)
  864. {
  865. _particleData.modeB.angle[i] += _particleData.modeB.degreesPerSecond[i] * dt;
  866. }
  867. for (int i = 0; i < _particleCount; ++i)
  868. {
  869. _particleData.modeB.radius[i] += _particleData.modeB.deltaRadius[i] * dt;
  870. }
  871. for (int i = 0; i < _particleCount; ++i)
  872. {
  873. _particleData.posx[i] = - cosf(_particleData.modeB.angle[i]) * _particleData.modeB.radius[i];
  874. }
  875. for (int i = 0; i < _particleCount; ++i)
  876. {
  877. _particleData.posy[i] = - sinf(_particleData.modeB.angle[i]) * _particleData.modeB.radius[i] * _yCoordFlipped;
  878. }
  879. if (modeA.rotationIsDir)
  880. {
  881. for (int i = 0; i < _particleCount; ++i)
  882. {
  883. Vec2 dir = Vec2(_particleData.posx[i] - _particleData.startPosX[i],_particleData.posy[i] - _particleData.startPosY[i]);
  884. _particleData.rotation[i] = -CC_RADIANS_TO_DEGREES(dir.getAngle()) + _startSpin;
  885. // CCLOG("angle : %f %f %f %f",dir.x,dir.y,dir.getAngle(),_particleData.rotation[i]);
  886. _particleData.startPosX[i] = _particleData.posx[i];
  887. _particleData.startPosY[i] = _particleData.posy[i];
  888. }
  889. }
  890. }
  891. //color r,g,b,a
  892. for (int i = 0 ; i < _particleCount; ++i)
  893. {
  894. _particleData.colorR[i] += _particleData.deltaColorR[i] * dt;
  895. }
  896. for (int i = 0 ; i < _particleCount; ++i)
  897. {
  898. _particleData.colorG[i] += _particleData.deltaColorG[i] * dt;
  899. }
  900. for (int i = 0 ; i < _particleCount; ++i)
  901. {
  902. _particleData.colorB[i] += _particleData.deltaColorB[i] * dt;
  903. }
  904. for (int i = 0 ; i < _particleCount; ++i)
  905. {
  906. // _particleData.colorA[i] += _particleData.deltaColorA[i] * dt;
  907. int index = _particleDataExpansion.lifePercentage[i];
  908. float deltaSizePercentage = _colorAChangeLaw[index] * 0.01;
  909. _particleData.colorA[i] = _particleDataExpansion.startColorA[i] + _particleDataExpansion.deltaColorAAllLife[i] * deltaSizePercentage;
  910. }
  911. //size
  912. for (int i = 0 ; i < _particleCount; ++i)
  913. {
  914. int index = _particleDataExpansion.lifePercentage[i];
  915. float deltaSizeWidthPercentage = _sizeWidthChangeLaw[index] * 0.01;
  916. _particleDataExpansion.sizeWidth[i] = (_particleDataExpansion.startSizeWidth[i] + _particleDataExpansion.deltaSizeWidthAllLife[i] * deltaSizeWidthPercentage);
  917. _particleDataExpansion.sizeWidth[i] = MAX(0, _particleDataExpansion.sizeWidth[i]);
  918. }
  919. if(_lockAspectRatio){
  920. for (int i = 0 ; i < _particleCount; ++i)
  921. {
  922. _particleDataExpansion.sizeHeight[i] = MAX(0, _particleDataExpansion.sizeWidth[i] * _aspectRatio);
  923. }
  924. } else {
  925. for (int i = 0 ; i < _particleCount; ++i)
  926. {
  927. int index = _particleDataExpansion.lifePercentage[i];
  928. float deltaSizeHeightPercentage = _sizeHeightChangeLaw[index] * 0.01;
  929. _particleDataExpansion.sizeHeight[i] = (_particleDataExpansion.startSizeHeighth[i] + _particleDataExpansion.deltaSizeHeightAllLife[i] * deltaSizeHeightPercentage);
  930. _particleDataExpansion.sizeHeight[i] = MAX(0, _particleDataExpansion.sizeHeight[i]);
  931. }
  932. }
  933. if (true){
  934. //index 序列帧
  935. if (_frameRate != FRAM_RATE_PLAY_ONCE_IN_ALL_LIFE){
  936. for (int i = 0 ; i < _particleCount; ++i)
  937. {
  938. float liveTime = _particleDataExpansion.life[i] - _particleData.timeToLive[i];
  939. int totalIndex = liveTime * _frameRate;
  940. totalIndex+= _particleDataExpansion.startTextureIndex[i];
  941. int index = totalIndex % _texNumber;
  942. //BulldogTool::Log("[update] Tex Index : %d %d %d %d",index,totalIndex,_texNumber,_particleCount);
  943. _particleDataExpansion.textureIndex[i] = index;
  944. }
  945. } else {
  946. if (_texNumber > 0)
  947. {
  948. for (int i = 0 ; i < _particleCount; ++i)
  949. {
  950. int index = _particleDataExpansion.lifePercentage[i];
  951. float deltaSizePercentage = index * 0.01;
  952. int totalIndex = (_texNumber - 1) * deltaSizePercentage;
  953. totalIndex+= _particleDataExpansion.startTextureIndex[i];
  954. int texindex = totalIndex % _texNumber;
  955. if (_particleDataExpansion.textureIndex[i] != texindex) {
  956. _particleDataExpansion.textureIndex[i] += 1;
  957. _particleDataExpansion.textureIndex[i] %= _texNumber;
  958. }
  959. }
  960. }
  961. }
  962. }
  963. //angle
  964. if (!modeA.rotationIsDir){
  965. //角度和速度相同不计算
  966. for (int i = 0 ; i < _particleCount; ++i)
  967. {
  968. // _particleData.rotation[i] += _particleData.deltaRotation[i] * dt;
  969. int index = _particleDataExpansion.lifePercentage[i];
  970. float deltaSizePercentage = _spinChangeLaw[index] * 0.01;
  971. _particleData.rotation[i] = (_particleDataExpansion.startRotation [i] + _particleDataExpansion.deltaRotationAllLife[i] * deltaSizePercentage);
  972. }
  973. }
  974. updateParticleQuads();
  975. _transformSystemDirty = false;
  976. // only update gl buffer when visible
  977. if (_visible && ! _batchNode)
  978. {
  979. postStep();
  980. }
  981. CC_PROFILER_STOP_CATEGORY(kProfilerCategoryParticles , "ZMLParticleSystem - update");
  982. }
  983. NS_RU_END