From a26c465cef93fd77ecc446427f1ecdfde7fbae1f Mon Sep 17 00:00:00 2001 From: shun-iwasawa Date: Jan 09 2019 09:13:31 +0000 Subject: Fix ParticlesFx Crash When Inputting Blank Vector Level To the Texture Port (#2459) * fix particlesfx crash * fix more particlesfx crash --- diff --git a/toonz/sources/stdfx/iwa_particlesengine.cpp b/toonz/sources/stdfx/iwa_particlesengine.cpp index d0a63c5..89261d8 100644 --- a/toonz/sources/stdfx/iwa_particlesengine.cpp +++ b/toonz/sources/stdfx/iwa_particlesengine.cpp @@ -39,7 +39,7 @@ void printTime(TStopWatch &sw, std::string name) { ss << '\n' << '\0'; TSystem::outputDebug(ss.str()); } -}; +}; // namespace //---- /*-----------------------------------------------------------------*/ @@ -209,7 +209,7 @@ void Iwa_Particles_Engine::roll_particles( std::vector lastframe, /*-テクスチャ素材のそれぞれのカラム長-*/ int &totalparticles, QList &particleOrigins, int genPartNum /*- 実際に生成したい粒子数 -*/ - ) { +) { particles_ranges ranges; int i; float xgravity, ygravity, windx, windy; @@ -240,7 +240,7 @@ void Iwa_Particles_Engine::roll_particles( /*- 出発する粒子のインデックス -*/ QList leavingPartIndex; if (myregions.size() && - values.source_ctrl_val != Iwa_TiledParticlesFx::CTRL_NONE) { + porttiles.find(values.source_ctrl_val) != porttiles.end()) { int partLeft = actualBirthParticles; while (partLeft > 0) { int PrePartLeft = partLeft; @@ -329,7 +329,7 @@ void Iwa_Particles_Engine::roll_particles( po.pos[1], /*- 座標を指定して発生 -*/ po.isUpward, /*- orientation を追加 -*/ (int)po.initSourceFrame) /*- 素材内の初期フレーム位置 -*/ - ); + ); } totalparticles++; } @@ -375,7 +375,7 @@ void Iwa_Particles_Engine::roll_particles( (int)po.level, lastframe[po.level], po.pos[0], po.pos[1], po.isUpward, (int)po.initSourceFrame) /*- 素材内の初期フレーム位置 -*/ - ); + ); } totalparticles++; } @@ -391,7 +391,7 @@ void Iwa_Particles_Engine::roll_particles( /*- 出発する粒子 -*/ ParticleOrigin po = particleOrigins.at(leavingPartIndex.at(i)); - int seed = (int)((std::numeric_limits::max)() * + int seed = (int)((std::numeric_limits::max)() * values.random_val->getFloat()); int lifetime = 0; @@ -410,7 +410,7 @@ void Iwa_Particles_Engine::roll_particles( 0, (int)po.level, lastframe[po.level], po.pos[0], po.pos[1], po.isUpward, (int)po.initSourceFrame) /*- 素材内の初期フレーム位置 -*/ - ); + ); } totalparticles++; } @@ -422,7 +422,7 @@ void Iwa_Particles_Engine::roll_particles( /*- 出発する粒子 -*/ ParticleOrigin po = particleOrigins.at(leavingPartIndex.at(i)); - int seed = (int)((std::numeric_limits::max)() * + int seed = (int)((std::numeric_limits::max)() * values.random_val->getFloat()); int lifetime = 0; @@ -438,7 +438,7 @@ void Iwa_Particles_Engine::roll_particles( (int)po.level, lastframe[po.level], po.pos[0], po.pos[1], po.isUpward, (int)po.initSourceFrame) /*- 素材内の初期フレーム位置 -*/ - ); + ); } totalparticles++; } @@ -488,10 +488,10 @@ void Iwa_Particles_Engine::normalize_values(struct particles_values &values, (values.speeda_val.first) = (values.speeda_val.first) * M_PI_180; (values.speeda_val.second) = (values.speeda_val.second) * M_PI_180; if (values.step_val < 1) values.step_val = 1; - values.genfadecol_val = (values.genfadecol_val) * 0.01; - values.finfadecol_val = (values.finfadecol_val) * 0.01; - values.foutfadecol_val = (values.foutfadecol_val) * 0.01; - (values.curl_val) = (values.curl_val) * dpicorr * 0.1; + values.genfadecol_val = (values.genfadecol_val) * 0.01; + values.finfadecol_val = (values.finfadecol_val) * 0.01; + values.foutfadecol_val = (values.foutfadecol_val) * 0.01; + (values.curl_val) = (values.curl_val) * dpicorr * 0.1; /*- ひらひら粒子に照明を当てる normalize_values()内で Degree → Radian 化する * -*/ (values.iw_light_theta_val) = (values.iw_light_theta_val) * M_PI_180; @@ -508,20 +508,18 @@ void Iwa_Particles_Engine::render_particles( std::vector part_ports, /*- テクスチャ素材画像のポート -*/ const TRenderSettings &ri, TDimension - &p_size, /*- テクスチャ素材のバウンディングボックスの足し合わさったもの - -*/ + &p_size, /*- テクスチャ素材のバウンディングボックスの足し合わさったもの + -*/ TPointD &p_offset, /*- バウンディングボックス左下の座標 -*/ std::map ctrl_ports, /*- コントロール画像のポート番号/ポート -*/ - std::vector - partLevel, /*- テクスチャ素材のリスト -*/ - float dpi, /*- 1 が入ってくる -*/ - int curr_frame, - int shrink, /*- 1 が入ってくる -*/ - double startx, /*- 0 が入ってくる -*/ - double starty, /*- 0 が入ってくる -*/ - double endx, /*- 0 が入ってくる -*/ - double endy, /*- 0 が入ってくる -*/ + std::vector partLevel, /*- テクスチャ素材のリスト -*/ + float dpi, /*- 1 が入ってくる -*/ + int curr_frame, int shrink, /*- 1 が入ってくる -*/ + double startx, /*- 0 が入ってくる -*/ + double starty, /*- 0 が入ってくる -*/ + double endx, /*- 0 が入ってくる -*/ + double endy, /*- 0 が入ってくる -*/ std::vector last_frame, /*- テクスチャ素材のそれぞれのカラム長 -*/ unsigned long fxId) { /*- 各種パーティクルのパラメータ -*/ @@ -739,7 +737,7 @@ void Iwa_Particles_Engine::render_particles( curr_frame, level_n, &random_level, 1, last_frame, totalparticles, particleOrigins, intpart /*- 実際に生成したい粒子数 -*/ - ); + ); // Store the rolled data in the particles manager if (!particlesData->m_calculated || @@ -918,9 +916,9 @@ void Iwa_Particles_Engine::do_render( /*- ここで、照明モードのとき、その明るさを計算する -*/ if (values.iw_rendermode_val == Iwa_TiledParticlesFx::REND_ILLUMINATED) { - float liTheta = values.iw_light_theta_val; - float liPhi = values.iw_light_phi_val; - float3 normVec = {sinf(theta) * sinf(phi), cosf(theta) * sinf(phi), + float liTheta = values.iw_light_theta_val; + float liPhi = values.iw_light_phi_val; + float3 normVec = {sinf(theta) * sinf(phi), cosf(theta) * sinf(phi), cosf(phi)}; float3 lightVec = {sinf(liTheta) * sinf(liPhi), cosf(liTheta) * sinf(liPhi), cosf(liPhi)}; @@ -1108,8 +1106,7 @@ void Iwa_Particles_Engine::fill_array( int ®ioncount, /*- 領域数を返す -*/ std::vector &myarray, /*- インデックスを返すと思われる。サイズはソースTileの縦横 -*/ - std::vector &lista, - std::vector &listb, int threshold) { + std::vector &lista, std::vector &listb, int threshold) { int pr = 0; int i, j; int lx, ly; @@ -1145,7 +1142,7 @@ void Iwa_Particles_Engine::fill_array( mask[1] = myarray[i - 1 + lx * (j - 1)]; } if (i != lx - 1) mask[3] = myarray[i + 1 + lx * (j - 1)]; - mask[2] = myarray[i + lx * (j - 1)]; + mask[2] = myarray[i + lx * (j - 1)]; if (!mask[0] && !mask[1] && !mask[2] && !mask[3]) { (regioncount)++; myarray[i + lx * j] = (regioncount); @@ -1179,7 +1176,7 @@ void Iwa_Particles_Engine::fill_array( void Iwa_Particles_Engine::normalize_array( std::vector> &myregions, TPointD pos, int lx, int ly, int regioncounter, std::vector &myarray, std::vector &lista, - std::vector &listb, std::vector & final) { + std::vector &listb, std::vector &final) { int i, j, k, l; std::vector tmp; @@ -1192,13 +1189,13 @@ void Iwa_Particles_Engine::normalize_array( j = lista[l]; /*TMSG_INFO("j vale %d\n", j);*/ while (final[j] != j) j = final[j]; - k = listb[l]; + k = listb[l]; /*TMSG_INFO("k vale %d\n", k);*/ while (final[k] != k) k = final[k]; - if (j != k) final[j] = k; + if (j != k) final[j] = k; } // TMSG_INFO("esco dal for\n"); - for (j = 1; j <= regioncounter; j++) + for (j = 1; j <= regioncounter; j++) while (final[j] != final[final[j]]) final[j] = final[final[j]]; /*conto quante cavolo di regioni sono*/ diff --git a/toonz/sources/stdfx/iwa_particlesfx.h b/toonz/sources/stdfx/iwa_particlesfx.h index 925f775..ee46c1f 100644 --- a/toonz/sources/stdfx/iwa_particlesfx.h +++ b/toonz/sources/stdfx/iwa_particlesfx.h @@ -132,7 +132,6 @@ public: ANIM_SR_CYCLE }; enum { TOP_YOUNGER, TOP_OLDER, TOP_SMALLER, TOP_BIGGER, TOP_RANDOM }; - enum { CTRL_NONE = -1, CTRL_1, CTRL_2 }; /*- 計算モード (背景+粒子/粒子/背景/照明された粒子) -*/ enum { REND_ALL, REND_PARTICLES, REND_BG, REND_ILLUMINATED }; diff --git a/toonz/sources/stdfx/particles.cpp b/toonz/sources/stdfx/particles.cpp index b2e4e6a..925c036 100644 --- a/toonz/sources/stdfx/particles.cpp +++ b/toonz/sources/stdfx/particles.cpp @@ -52,7 +52,8 @@ Particle::Particle(int g_lifetime, int seed, std::map porttiles, /*- 初期座標値をつくる -*/ /*-- Perspective DistributionがONかつ、SizeのControlImageが刺さっている場合 * --*/ - if (myregions.size() && values.scale_ctrl_val != ParticlesFx::CTRL_NONE && + if (myregions.size() && + porttiles.find(values.scale_ctrl_val) != porttiles.end() && values.perspective_distribution_val) { float size = myWeight[255]; /*- 候補の中のIndex -*/ @@ -74,7 +75,7 @@ Particle::Particle(int g_lifetime, int seed, std::map porttiles, } /*- 領域がある かつ 発生領域のControlImageが刺さっている場合 -*/ else if (myregions.size() && - values.source_ctrl_val != ParticlesFx::CTRL_NONE) { + porttiles.find(values.source_ctrl_val) != porttiles.end()) { /*- howmany:発生Particlesのうち、何番目に発生させたものか。 myregionが複数有る場合は、均等に割り振ることになる。 -*/ int regionindex = howmany % myregions.size(); @@ -117,7 +118,8 @@ Particle::Particle(int g_lifetime, int seed, std::map porttiles, it != porttiles.end(); ++it) { if ((values.lifetime_ctrl_val == it->first || values.speed_ctrl_val == it->first || - values.scale_ctrl_val == it->first || values.rot_ctrl_val == it->first + values.scale_ctrl_val == it->first || + values.rot_ctrl_val == it->first /*- Speed Angleを明るさでコントロールする場合 -*/ || (values.speeda_ctrl_val == it->first && !values.speeda_use_gradient_val)) && @@ -245,7 +247,7 @@ void Particle::create_Swing(const particles_values &values, smperiody = changesigny; } if (values.rotswingmode_val == ParticlesFx::SWING_SMOOTH) { - smswinga = abs((int)(values.rotsca_val.first + + smswinga = abs((int)(values.rotsca_val.first + random.getFloat() * (ranges.rotsca_range))); smperioda = changesigna; } @@ -267,7 +269,7 @@ void Particle::create_Colors(const particles_values &values, (porttiles.find(values.gencol_ctrl_val) != porttiles.end())) get_image_reference(porttiles[values.gencol_ctrl_val], values, color); else - color = values.gencol_val.getPremultipliedValue(random.getFloat()); + color = values.gencol_val.getPremultipliedValue(random.getFloat()); gencol.fadecol = values.genfadecol_val; if (values.gencol_spread_val) spread_color(color, values.gencol_spread_val); gencol.col = color; @@ -394,7 +396,7 @@ void Particle::update_Animation(const particles_values &values, int first, case ParticlesFx::ANIM_SR_CYCLE: if (!keep || frame != keep - 1) { if (!animswing && frame < last - 1) { - frame = (frame + 1); + frame = (frame + 1); if (frame == last - 1) animswing = 1; } else frame = (frame - 1); @@ -711,7 +713,7 @@ void Particle::move(std::map porttiles, frictx = vx * (1 + values.friction_val * frictreference) + (10 / vx) * values.friction_val * frictreference; if ((frictx / vx) < 0) frictx = 0; - vx = frictx; + vx = frictx; } if (!frictx && fabs(values.friction_val * frictreference * 10) > fabs(xgravity)) { @@ -725,7 +727,7 @@ void Particle::move(std::map porttiles, fricty = vy * (1 + values.friction_val * frictreference) + (10 / vy) * values.friction_val * frictreference; if ((fricty / vy) < 0) fricty = 0; - vy = fricty; + vy = fricty; } if (!fricty && fabs(values.friction_val * frictreference * 10) > fabs(ygravity)) { diff --git a/toonz/sources/stdfx/particlesengine.cpp b/toonz/sources/stdfx/particlesengine.cpp index 1a480db..2abf548 100644 --- a/toonz/sources/stdfx/particlesengine.cpp +++ b/toonz/sources/stdfx/particlesengine.cpp @@ -256,7 +256,7 @@ void Particles_Engine::roll_particles( { /*- 新たに作るパーティクルの数だけ繰り返す -*/ for (i = 0; i < newparticles; i++) { - int seed = (int)((std::numeric_limits::max)() * + int seed = (int)((std::numeric_limits::max)() * values.random_val->getFloat()); int level = (int)(values.random_val->getFloat() * level_n); @@ -292,7 +292,7 @@ void Particles_Engine::roll_particles( switch (values.toplayer_val) { case ParticlesFx::TOP_YOUNGER: for (i = 0; i < newparticles; i++) { - int seed = (int)((std::numeric_limits::max)() * + int seed = (int)((std::numeric_limits::max)() * values.random_val->getFloat()); int level = (int)(values.random_val->getFloat() * level_n); @@ -321,7 +321,7 @@ void Particles_Engine::roll_particles( for (int j = 0; j < tmp; j++, it++) ; { - int seed = (int)((std::numeric_limits::max)() * + int seed = (int)((std::numeric_limits::max)() * values.random_val->getFloat()); int level = (int)(values.random_val->getFloat() * level_n); int lifetime = 0; @@ -345,7 +345,7 @@ void Particles_Engine::roll_particles( default: for (i = 0; i < newparticles; i++) { - int seed = (int)((std::numeric_limits::max)() * + int seed = (int)((std::numeric_limits::max)() * values.random_val->getFloat()); int level = (int)(values.random_val->getFloat() * level_n); int lifetime = 0; @@ -403,9 +403,9 @@ void Particles_Engine::normalize_values(struct particles_values &values, (values.speeda_val.first) = (values.speeda_val.first) * M_PI_180; (values.speeda_val.second) = (values.speeda_val.second) * M_PI_180; if (values.step_val < 1) values.step_val = 1; - values.genfadecol_val = (values.genfadecol_val) * 0.01; - values.finfadecol_val = (values.finfadecol_val) * 0.01; - values.foutfadecol_val = (values.foutfadecol_val) * 0.01; + values.genfadecol_val = (values.genfadecol_val) * 0.01; + values.finfadecol_val = (values.finfadecol_val) * 0.01; + values.foutfadecol_val = (values.foutfadecol_val) * 0.01; } /*-----------------------------------------------------------------*/ @@ -682,7 +682,7 @@ void Particles_Engine::do_render( // either // (std::numeric_limits::max)() or its opposite, then the rect IS // THE infiniteRectD) - if (bbox == TConsts::infiniteRectD) return; + if (bbox.isEmpty() || bbox == TConsts::infiniteRectD) return; } // Now, these are the particle rendering specifications @@ -861,7 +861,7 @@ void Particles_Engine::fill_array(TTile *ctrl1, int ®ioncount, mask[1] = myarray[i - 1 + lx * (j - 1)]; } if (i != lx - 1) mask[3] = myarray[i + 1 + lx * (j - 1)]; - mask[2] = myarray[i + lx * (j - 1)]; + mask[2] = myarray[i + lx * (j - 1)]; if (!mask[0] && !mask[1] && !mask[2] && !mask[3]) { (regioncount)++; myarray[i + lx * j] = (regioncount); @@ -895,7 +895,7 @@ void Particles_Engine::fill_array(TTile *ctrl1, int ®ioncount, void Particles_Engine::normalize_array( std::vector> &myregions, TPointD pos, int lx, int ly, int regioncounter, std::vector &myarray, std::vector &lista, - std::vector &listb, std::vector & final) { + std::vector &listb, std::vector &final) { int i, j, k, l; std::vector tmp; @@ -908,13 +908,13 @@ void Particles_Engine::normalize_array( j = lista[l]; /*TMSG_INFO("j vale %d\n", j);*/ while (final[j] != j) j = final[j]; - k = listb[l]; + k = listb[l]; /*TMSG_INFO("k vale %d\n", k);*/ while (final[k] != k) k = final[k]; - if (j != k) final[j] = k; + if (j != k) final[j] = k; } // TMSG_INFO("esco dal for\n"); - for (j = 1; j <= regioncounter; j++) + for (j = 1; j <= regioncounter; j++) while (final[j] != final[final[j]]) final[j] = final[final[j]]; /*conto quante cavolo di regioni sono*/ diff --git a/toonz/sources/stdfx/particlesfx.cpp b/toonz/sources/stdfx/particlesfx.cpp index b12c692..31e8743 100644 --- a/toonz/sources/stdfx/particlesfx.cpp +++ b/toonz/sources/stdfx/particlesfx.cpp @@ -230,7 +230,7 @@ ParticlesFx::ParticlesFx() step_val->setValueRange(1, (std::numeric_limits::max)()); TSpectrum::ColorKey colors[] = {TSpectrum::ColorKey(0, TPixel32::Red), TSpectrum::ColorKey(1, TPixel32::Red)}; - gencol_val = TSpectrumParamP(tArrayCount(colors), colors); + gencol_val = TSpectrumParamP(tArrayCount(colors), colors); bindParam(this, "birth_color", gencol_val); bindParam(this, "birth_color_ctrl", gencol_ctrl_val); bindParam(this, "birth_color_spread", gencol_spread_val); @@ -436,6 +436,7 @@ void ParticlesFx::doCompute(TTile &tile, double frame, } } + if (bbox.isEmpty()) return; if (bbox == TConsts::infiniteRectD) bbox *= outTileBBox; p_size.lx = (int)bbox.getLx() + 1; diff --git a/toonz/sources/stdfx/particlesfx.h b/toonz/sources/stdfx/particlesfx.h index 2418b2c..3a45aab 100644 --- a/toonz/sources/stdfx/particlesfx.h +++ b/toonz/sources/stdfx/particlesfx.h @@ -104,7 +104,6 @@ public: ANIM_SR_CYCLE }; enum { TOP_YOUNGER, TOP_OLDER, TOP_SMALLER, TOP_BIGGER, TOP_RANDOM }; - enum { CTRL_NONE = -1, CTRL_1, CTRL_2 }; public: ParticlesFx();