Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenkernel / intern / particle_child.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) Blender Foundation
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Lukas Toenne
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/blenkernel/intern/particle_child.c
29  *  \ingroup bke
30  */
31
32 #include "BLI_math.h"
33 #include "BLI_noise.h"
34
35 #include "DNA_material_types.h"
36
37 #include "BKE_colortools.h"
38 #include "BKE_particle.h"
39
40 #include "particle_private.h"
41
42 struct Material;
43
44 static void get_strand_normal(Material *ma, const float surfnor[3], float surfdist, float nor[3])
45 {
46         float cross[3], nstrand[3], vnor[3], blend;
47
48         if (!((ma->mode & MA_STR_SURFDIFF) || (ma->strand_surfnor > 0.0f)))
49                 return;
50
51         if (ma->mode & MA_STR_SURFDIFF) {
52                 cross_v3_v3v3(cross, surfnor, nor);
53                 cross_v3_v3v3(nstrand, nor, cross);
54
55                 blend = dot_v3v3(nstrand, surfnor);
56                 CLAMP(blend, 0.0f, 1.0f);
57
58                 interp_v3_v3v3(vnor, nstrand, surfnor, blend);
59                 normalize_v3(vnor);
60         }
61         else {
62                 copy_v3_v3(vnor, nor);
63         }
64
65         if (ma->strand_surfnor > 0.0f) {
66                 if (ma->strand_surfnor > surfdist) {
67                         blend = (ma->strand_surfnor - surfdist) / ma->strand_surfnor;
68                         interp_v3_v3v3(vnor, vnor, surfnor, blend);
69                         normalize_v3(vnor);
70                 }
71         }
72
73         copy_v3_v3(nor, vnor);
74 }
75
76 /* ------------------------------------------------------------------------- */
77
78 typedef struct ParticlePathIterator {
79         ParticleCacheKey *key;
80         int index;
81         float time;
82
83         ParticleCacheKey *parent_key;
84         float parent_rotation[4];
85 } ParticlePathIterator;
86
87 static void psys_path_iter_get(ParticlePathIterator *iter, ParticleCacheKey *keys, int totkeys,
88                                ParticleCacheKey *parent, int index)
89 {
90         BLI_assert(index >= 0 && index < totkeys);
91
92         iter->key = keys + index;
93         iter->index = index;
94         iter->time = (float)index / (float)(totkeys - 1);
95
96         if (parent) {
97                 iter->parent_key = parent + index;
98                 if (index > 0)
99                         mul_qt_qtqt(iter->parent_rotation, iter->parent_key->rot, parent->rot);
100                 else
101                         copy_qt_qt(iter->parent_rotation, parent->rot);
102         }
103         else {
104                 iter->parent_key = NULL;
105                 unit_qt(iter->parent_rotation);
106         }
107 }
108
109 typedef struct ParticlePathModifier {
110         struct ParticlePathModifier *next, *prev;
111
112         void (*apply)(ParticleCacheKey *keys, int totkeys, ParticleCacheKey *parent_keys);
113 } ParticlePathModifier;
114
115 /* ------------------------------------------------------------------------- */
116
117 static void do_kink_spiral_deform(ParticleKey *state, const float dir[3], const float kink[3],
118                                   float time, float freq, float shape, float amplitude,
119                                   const float spiral_start[3])
120 {
121         float result[3];
122
123         CLAMP(time, 0.f, 1.f);
124
125         copy_v3_v3(result, state->co);
126
127         {
128                 /* Creates a logarithmic spiral:
129                  *   r(theta) = a * exp(b * theta)
130                  *
131                  * The "density" parameter b is defined by the shape parameter
132                  * and goes up to the Golden Spiral for 1.0
133                  * https://en.wikipedia.org/wiki/Golden_spiral
134                  */
135                 const float b = shape * (1.0f + sqrtf(5.0f)) / (float)M_PI * 0.25f;
136                 /* angle of the spiral against the curve (rotated opposite to make a smooth transition) */
137                 const float start_angle = ((b != 0.0f) ? atanf(1.0f / b) :
138                                            (float)-M_PI_2) + (b > 0.0f ? -(float)M_PI_2 : (float)M_PI_2);
139
140                 float spiral_axis[3], rot[3][3];
141                 float vec[3];
142
143                 float theta = freq * time * 2.0f * (float)M_PI;
144                 float radius = amplitude * expf(b * theta);
145
146                 /* a bit more intuitive than using negative frequency for this */
147                 if (amplitude < 0.0f)
148                         theta = -theta;
149
150                 cross_v3_v3v3(spiral_axis, dir, kink);
151                 normalize_v3(spiral_axis);
152
153                 mul_v3_v3fl(vec, kink, -radius);
154
155                 axis_angle_normalized_to_mat3(rot, spiral_axis, theta);
156                 mul_m3_v3(rot, vec);
157
158                 madd_v3_v3fl(vec, kink, amplitude);
159
160                 axis_angle_normalized_to_mat3(rot, spiral_axis, -start_angle);
161                 mul_m3_v3(rot, vec);
162
163                 add_v3_v3v3(result, spiral_start, vec);
164         }
165
166         copy_v3_v3(state->co, result);
167 }
168
169 static void do_kink_spiral(ParticleThreadContext *ctx, ParticleTexture *ptex, const float parent_orco[3],
170                            ChildParticle *cpa, const float orco[3], float hairmat[4][4],
171                            ParticleCacheKey *keys, ParticleCacheKey *parent_keys, int *r_totkeys, float *r_max_length)
172 {
173         struct ParticleSettings *part = ctx->sim.psys->part;
174         const int seed = ctx->sim.psys->child_seed + (int)(cpa - ctx->sim.psys->child);
175         const int totkeys = ctx->segments + 1;
176         const int extrakeys = ctx->extra_segments;
177
178         float kink_amp_random = part->kink_amp_random;
179         float kink_amp = part->kink_amp * (1.0f - kink_amp_random * psys_frand(ctx->sim.psys, 93541 + seed));
180         float kink_freq = part->kink_freq;
181         float kink_shape = part->kink_shape;
182         float kink_axis_random = part->kink_axis_random;
183         float rough1 = part->rough1;
184         float rough2 = part->rough2;
185         float rough_end = part->rough_end;
186
187         ParticlePathIterator iter;
188         ParticleCacheKey *key;
189         int k;
190
191         float dir[3];
192         float spiral_start[3] = {0.0f, 0.0f, 0.0f};
193         float spiral_start_time = 0.0f;
194         float spiral_par_co[3] = {0.0f, 0.0f, 0.0f};
195         float spiral_par_vel[3] = {0.0f, 0.0f, 0.0f};
196         float spiral_par_rot[4] = {1.0f, 0.0f, 0.0f, 0.0f};
197         float totlen;
198         float cut_time;
199         int start_index = 0, end_index = 0;
200         float kink_base[3];
201
202         if (ptex) {
203                 kink_amp *= ptex->kink_amp;
204                 kink_freq *= ptex->kink_freq;
205                 rough1 *= ptex->rough1;
206                 rough2 *= ptex->rough2;
207                 rough_end *= ptex->roughe;
208         }
209
210         cut_time = (totkeys - 1) * ptex->length;
211         zero_v3(spiral_start);
212
213         for (k = 0, key = keys; k < totkeys-1; k++, key++) {
214                 if ((float)(k + 1) >= cut_time) {
215                         float fac = cut_time - (float)k;
216                         ParticleCacheKey *par = parent_keys + k;
217
218                         start_index = k + 1;
219                         end_index = start_index + extrakeys;
220
221                         spiral_start_time = ((float)k + fac) / (float)(totkeys - 1);
222                         interp_v3_v3v3(spiral_start, key->co, (key+1)->co, fac);
223
224                         interp_v3_v3v3(spiral_par_co, par->co, (par+1)->co, fac);
225                         interp_v3_v3v3(spiral_par_vel, par->vel, (par+1)->vel, fac);
226                         interp_qt_qtqt(spiral_par_rot, par->rot, (par+1)->rot, fac);
227
228                         break;
229                 }
230         }
231
232         zero_v3(dir);
233
234         zero_v3(kink_base);
235         kink_base[part->kink_axis] = 1.0f;
236         mul_mat3_m4_v3(ctx->sim.ob->obmat, kink_base);
237
238         for (k = 0, key = keys; k < end_index; k++, key++) {
239                 float par_time;
240                 float *par_co, *par_vel, *par_rot;
241
242                 psys_path_iter_get(&iter, keys, end_index, NULL, k);
243                 if (k < start_index) {
244                         sub_v3_v3v3(dir, (key+1)->co, key->co);
245                         normalize_v3(dir);
246
247                         par_time = (float)k / (float)(totkeys - 1);
248                         par_co = parent_keys[k].co;
249                         par_vel = parent_keys[k].vel;
250                         par_rot = parent_keys[k].rot;
251                 }
252                 else {
253                         float spiral_time = (float)(k - start_index) / (float)(extrakeys-1);
254                         float kink[3], tmp[3];
255
256                         /* use same time value for every point on the spiral */
257                         par_time = spiral_start_time;
258                         par_co = spiral_par_co;
259                         par_vel = spiral_par_vel;
260                         par_rot = spiral_par_rot;
261
262                         project_v3_v3v3(tmp, kink_base, dir);
263                         sub_v3_v3v3(kink, kink_base, tmp);
264                         normalize_v3(kink);
265
266                         if (kink_axis_random > 0.0f) {
267                                 float a = kink_axis_random * (psys_frand(ctx->sim.psys, 7112 + seed) * 2.0f - 1.0f) * (float)M_PI;
268                                 float rot[3][3];
269
270                                 axis_angle_normalized_to_mat3(rot, dir, a);
271                                 mul_m3_v3(rot, kink);
272                         }
273
274                         do_kink_spiral_deform((ParticleKey *)key, dir, kink, spiral_time, kink_freq, kink_shape, kink_amp, spiral_start);
275                 }
276
277                 /* apply different deformations to the child path */
278                 do_child_modifiers(ctx, &ctx->sim, ptex, par_co, par_vel, par_rot, parent_orco, cpa, orco, hairmat, (ParticleKey *)key, par_time);
279         }
280
281         totlen = 0.0f;
282         for (k = 0, key = keys; k < end_index-1; k++, key++)
283                 totlen += len_v3v3((key+1)->co, key->co);
284
285         *r_totkeys = end_index;
286         *r_max_length = totlen;
287 }
288
289 /* ------------------------------------------------------------------------- */
290
291 static bool check_path_length(int k, ParticleCacheKey *keys, ParticleCacheKey *key, float max_length, float step_length, float *cur_length, float dvec[3])
292 {
293         if (*cur_length + step_length > max_length) {
294                 sub_v3_v3v3(dvec, key->co, (key-1)->co);
295                 mul_v3_fl(dvec, (max_length - *cur_length) / step_length);
296                 add_v3_v3v3(key->co, (key-1)->co, dvec);
297                 keys->segments = k;
298                 /* something over the maximum step value */
299                 return false;
300         }
301         else {
302                 *cur_length += step_length;
303                 return true;
304         }
305 }
306
307 void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *modifiers,
308                                 ChildParticle *cpa, ParticleTexture *ptex, const float orco[3], const float ornor[3], float hairmat[4][4],
309                                 ParticleCacheKey *keys, ParticleCacheKey *parent_keys, const float parent_orco[3])
310 {
311         struct ParticleSettings *part = ctx->sim.psys->part;
312         struct Material *ma = ctx->ma;
313         const bool draw_col_ma = (part->draw_col == PART_DRAW_COL_MAT);
314         const bool use_length_check = !ELEM(part->kink, PART_KINK_SPIRAL);
315
316         ParticlePathModifier *mod;
317         ParticleCacheKey *key;
318         int totkeys, k;
319         float max_length;
320
321 #if 0 /* TODO for the future: use true particle modifiers that work on the whole curve */
322         for (mod = modifiers->first; mod; mod = mod->next) {
323                 mod->apply(keys, totkeys, parent_keys);
324         }
325 #else
326         (void)modifiers;
327         (void)mod;
328
329         if (part->kink == PART_KINK_SPIRAL) {
330                 do_kink_spiral(ctx, ptex, parent_orco, cpa, orco, hairmat, keys, parent_keys, &totkeys, &max_length);
331                 keys->segments = totkeys - 1;
332         }
333         else {
334                 ParticlePathIterator iter;
335
336                 totkeys = ctx->segments + 1;
337                 max_length = ptex->length;
338
339                 for (k = 0, key = keys; k < totkeys; k++, key++) {
340                         ParticleKey *par;
341
342                         psys_path_iter_get(&iter, keys, totkeys, parent_keys, k);
343                         par = (ParticleKey *)iter.parent_key;
344
345                         /* apply different deformations to the child path */
346                         do_child_modifiers(ctx, &ctx->sim, ptex, par->co, par->vel, iter.parent_rotation, parent_orco, cpa, orco, hairmat, (ParticleKey *)key, iter.time);
347                 }
348         }
349
350         {
351                 const float step_length = 1.0f / (float)(totkeys - 1);
352                 float cur_length = 0.0f;
353
354                 if (max_length <= 0.0f) {
355                         keys->segments = -1;
356                         totkeys = 0;
357                 }
358
359                 /* we have to correct velocity because of kink & clump */
360                 for (k = 0, key = keys; k < totkeys; ++k, ++key) {
361                         if (k >= 2) {
362                                 sub_v3_v3v3((key-1)->vel, key->co, (key-2)->co);
363                                 mul_v3_fl((key-1)->vel, 0.5);
364
365                                 if (ma && draw_col_ma)
366                                         get_strand_normal(ma, ornor, cur_length, (key-1)->vel);
367                         }
368
369                         if (use_length_check && k > 1) {
370                                 float dvec[3];
371                                 /* check if path needs to be cut before actual end of data points */
372                                 if (!check_path_length(k, keys, key, max_length, step_length, &cur_length, dvec)) {
373                                         /* last key */
374                                         sub_v3_v3v3(key->vel, key->co, (key-1)->co);
375                                         if (ma && draw_col_ma) {
376                                                 copy_v3_v3(key->col, &ma->r);
377                                         }
378                                         break;
379                                 }
380                         }
381                         if (k == totkeys-1) {
382                                 /* last key */
383                                 sub_v3_v3v3(key->vel, key->co, (key-1)->co);
384                         }
385
386                         if (ma && draw_col_ma) {
387                                 copy_v3_v3(key->col, &ma->r);
388                                 get_strand_normal(ma, ornor, cur_length, key->vel);
389                         }
390                 }
391         }
392 #endif
393 }
394
395 /* ------------------------------------------------------------------------- */
396
397 void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], const float par_rot[4], float time, float freq, float shape,
398              float amplitude, float flat, short type, short axis, float obmat[4][4], int smooth_start)
399 {
400         float kink[3] = {1.f, 0.f, 0.f}, par_vec[3], q1[4] = {1.f, 0.f, 0.f, 0.f};
401         float t, dt = 1.f, result[3];
402
403         if (ELEM(type, PART_KINK_NO, PART_KINK_SPIRAL))
404                 return;
405
406         CLAMP(time, 0.f, 1.f);
407
408         if (shape != 0.0f && !ELEM(type, PART_KINK_BRAID)) {
409                 if (shape < 0.0f)
410                         time = (float)pow(time, 1.f + shape);
411                 else
412                         time = (float)pow(time, 1.f / (1.f - shape));
413         }
414
415         t = time * freq * (float)M_PI;
416
417         if (smooth_start) {
418                 dt = fabsf(t);
419                 /* smooth the beginning of kink */
420                 CLAMP(dt, 0.f, (float)M_PI);
421                 dt = sinf(dt / 2.f);
422         }
423
424         if (!ELEM(type, PART_KINK_RADIAL)) {
425                 float temp[3];
426
427                 kink[axis] = 1.f;
428
429                 if (obmat)
430                         mul_mat3_m4_v3(obmat, kink);
431
432                 mul_qt_v3(par_rot, kink);
433
434                 /* make sure kink is normal to strand */
435                 project_v3_v3v3(temp, kink, par_vel);
436                 sub_v3_v3(kink, temp);
437                 normalize_v3(kink);
438         }
439
440         copy_v3_v3(result, state->co);
441         sub_v3_v3v3(par_vec, par_co, state->co);
442
443         switch (type) {
444                 case PART_KINK_CURL:
445                 {
446                         float curl_offset[3];
447
448                         /* rotate kink vector around strand tangent */
449                         mul_v3_v3fl(curl_offset, kink, amplitude);
450                         axis_angle_to_quat(q1, par_vel, t);
451                         mul_qt_v3(q1, curl_offset);
452
453                         interp_v3_v3v3(par_vec, state->co, par_co, flat);
454                         add_v3_v3v3(result, par_vec, curl_offset);
455                         break;
456                 }
457                 case PART_KINK_RADIAL:
458                 {
459                         if (flat > 0.f) {
460                                 float proj[3];
461                                 /* flatten along strand */
462                                 project_v3_v3v3(proj, par_vec, par_vel);
463                                 madd_v3_v3fl(result, proj, flat);
464                         }
465
466                         madd_v3_v3fl(result, par_vec, -amplitude * sinf(t));
467                         break;
468                 }
469                 case PART_KINK_WAVE:
470                 {
471                         madd_v3_v3fl(result, kink, amplitude * sinf(t));
472
473                         if (flat > 0.f) {
474                                 float proj[3];
475                                 /* flatten along wave */
476                                 project_v3_v3v3(proj, par_vec, kink);
477                                 madd_v3_v3fl(result, proj, flat);
478
479                                 /* flatten along strand */
480                                 project_v3_v3v3(proj, par_vec, par_vel);
481                                 madd_v3_v3fl(result, proj, flat);
482                         }
483                         break;
484                 }
485                 case PART_KINK_BRAID:
486                 {
487                         float y_vec[3] = {0.f, 1.f, 0.f};
488                         float z_vec[3] = {0.f, 0.f, 1.f};
489                         float vec_one[3], state_co[3];
490                         float inp_y, inp_z, length;
491
492                         if (par_rot) {
493                                 mul_qt_v3(par_rot, y_vec);
494                                 mul_qt_v3(par_rot, z_vec);
495                         }
496
497                         negate_v3(par_vec);
498                         normalize_v3_v3(vec_one, par_vec);
499
500                         inp_y = dot_v3v3(y_vec, vec_one);
501                         inp_z = dot_v3v3(z_vec, vec_one);
502
503                         if (inp_y > 0.5f) {
504                                 copy_v3_v3(state_co, y_vec);
505
506                                 mul_v3_fl(y_vec, amplitude * cosf(t));
507                                 mul_v3_fl(z_vec, amplitude / 2.f * sinf(2.f * t));
508                         }
509                         else if (inp_z > 0.0f) {
510                                 mul_v3_v3fl(state_co, z_vec, sinf((float)M_PI / 3.f));
511                                 madd_v3_v3fl(state_co, y_vec, -0.5f);
512
513                                 mul_v3_fl(y_vec, -amplitude * cosf(t + (float)M_PI / 3.f));
514                                 mul_v3_fl(z_vec, amplitude / 2.f * cosf(2.f * t + (float)M_PI / 6.f));
515                         }
516                         else {
517                                 mul_v3_v3fl(state_co, z_vec, -sinf((float)M_PI / 3.f));
518                                 madd_v3_v3fl(state_co, y_vec, -0.5f);
519
520                                 mul_v3_fl(y_vec, amplitude * -sinf(t + (float)M_PI / 6.f));
521                                 mul_v3_fl(z_vec, amplitude / 2.f * -sinf(2.f * t + (float)M_PI / 3.f));
522                         }
523
524                         mul_v3_fl(state_co, amplitude);
525                         add_v3_v3(state_co, par_co);
526                         sub_v3_v3v3(par_vec, state->co, state_co);
527
528                         length = normalize_v3(par_vec);
529                         mul_v3_fl(par_vec, MIN2(length, amplitude / 2.f));
530
531                         add_v3_v3v3(state_co, par_co, y_vec);
532                         add_v3_v3(state_co, z_vec);
533                         add_v3_v3(state_co, par_vec);
534
535                         shape = 2.f * (float)M_PI * (1.f + shape);
536
537                         if (t < shape) {
538                                 shape = t / shape;
539                                 shape = (float)sqrt((double)shape);
540                                 interp_v3_v3v3(result, result, state_co, shape);
541                         }
542                         else {
543                                 copy_v3_v3(result, state_co);
544                         }
545                         break;
546                 }
547         }
548
549         /* blend the start of the kink */
550         if (dt < 1.f)
551                 interp_v3_v3v3(state->co, state->co, result, dt);
552         else
553                 copy_v3_v3(state->co, result);
554 }
555
556 static float do_clump_level(float result[3], const float co[3], const float par_co[3], float time,
557                             float clumpfac, float clumppow, float pa_clump, CurveMapping *clumpcurve)
558 {
559         float clump = 0.0f;
560
561         if (clumpcurve) {
562                 clump = pa_clump * (1.0f - clamp_f(curvemapping_evaluateF(clumpcurve, 0, time), 0.0f, 1.0f));
563
564                 interp_v3_v3v3(result, co, par_co, clump);
565         }
566         else if (clumpfac != 0.0f) {
567                 float cpow;
568
569                 if (clumppow < 0.0f)
570                         cpow = 1.0f + clumppow;
571                 else
572                         cpow = 1.0f + 9.0f * clumppow;
573
574                 if (clumpfac < 0.0f) /* clump roots instead of tips */
575                         clump = -clumpfac * pa_clump * (float)pow(1.0 - (double)time, (double)cpow);
576                 else
577                         clump = clumpfac * pa_clump * (float)pow((double)time, (double)cpow);
578
579                 interp_v3_v3v3(result, co, par_co, clump);
580         }
581
582         return clump;
583 }
584
585 float do_clump(ParticleKey *state, const float par_co[3], float time, const float orco_offset[3], float clumpfac, float clumppow, float pa_clump,
586                bool use_clump_noise, float clump_noise_size, CurveMapping *clumpcurve)
587 {
588         float clump;
589
590         if (use_clump_noise && clump_noise_size != 0.0f) {
591                 float center[3], noisevec[3];
592                 float da[4], pa[12];
593
594                 mul_v3_v3fl(noisevec, orco_offset, 1.0f / clump_noise_size);
595                 voronoi(noisevec[0], noisevec[1], noisevec[2], da, pa, 1.0f, 0);
596                 mul_v3_fl(&pa[0], clump_noise_size);
597                 add_v3_v3v3(center, par_co, &pa[0]);
598
599                 do_clump_level(state->co, state->co, center, time, clumpfac, clumppow, pa_clump, clumpcurve);
600         }
601
602         clump = do_clump_level(state->co, state->co, par_co, time, clumpfac, clumppow, pa_clump, clumpcurve);
603
604         return clump;
605 }
606
607 static void do_rough(const float loc[3], float mat[4][4], float t, float fac, float size, float thres, ParticleKey *state)
608 {
609         float rough[3];
610         float rco[3];
611
612         if (thres != 0.0f) {
613                 if (fabsf((float)(-1.5f + loc[0] + loc[1] + loc[2])) < 1.5f * thres) {
614                         return;
615                 }
616         }
617
618         copy_v3_v3(rco, loc);
619         mul_v3_fl(rco, t);
620         rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2);
621         rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2);
622         rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2);
623
624         madd_v3_v3fl(state->co, mat[0], fac * rough[0]);
625         madd_v3_v3fl(state->co, mat[1], fac * rough[1]);
626         madd_v3_v3fl(state->co, mat[2], fac * rough[2]);
627 }
628
629 static void do_rough_end(const float loc[3], float mat[4][4], float t, float fac, float shape, ParticleKey *state)
630 {
631         float rough[2];
632         float roughfac;
633
634         roughfac = fac * (float)pow((double)t, shape);
635         copy_v2_v2(rough, loc);
636         rough[0] = -1.0f + 2.0f * rough[0];
637         rough[1] = -1.0f + 2.0f * rough[1];
638         mul_v2_fl(rough, roughfac);
639
640         madd_v3_v3fl(state->co, mat[0], rough[0]);
641         madd_v3_v3fl(state->co, mat[1], rough[1]);
642 }
643
644 static void do_rough_curve(const float loc[3], float mat[4][4], float time, float fac, float size, CurveMapping *roughcurve, ParticleKey *state)
645 {
646         float rough[3];
647         float rco[3];
648
649         if (!roughcurve)
650                 return;
651
652         fac *= clamp_f(curvemapping_evaluateF(roughcurve, 0, time), 0.0f, 1.0f);
653
654         copy_v3_v3(rco, loc);
655         mul_v3_fl(rco, time);
656         rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2);
657         rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2);
658         rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2);
659
660         madd_v3_v3fl(state->co, mat[0], fac * rough[0]);
661         madd_v3_v3fl(state->co, mat[1], fac * rough[1]);
662         madd_v3_v3fl(state->co, mat[2], fac * rough[2]);
663 }
664
665 void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim, ParticleTexture *ptex,
666                         const float par_co[3], const float par_vel[3], const float par_rot[4], const float par_orco[3],
667                         ChildParticle *cpa, const float orco[3], float mat[4][4], ParticleKey *state, float t)
668 {
669         ParticleSettings *part = sim->psys->part;
670         CurveMapping *clumpcurve = NULL, *roughcurve = NULL;
671         int i = cpa - sim->psys->child;
672         int guided = 0;
673
674         if (part->child_flag & PART_CHILD_USE_CLUMP_CURVE) {
675                 clumpcurve = (ctx != NULL) ? ctx->clumpcurve : part->clumpcurve;
676         }
677         if (part->child_flag & PART_CHILD_USE_ROUGH_CURVE) {
678                 roughcurve = (ctx != NULL) ? ctx->roughcurve : part->roughcurve;
679         }
680
681         float kink_amp = part->kink_amp;
682         float kink_amp_clump = part->kink_amp_clump;
683         float kink_freq = part->kink_freq;
684         float rough1 = part->rough1;
685         float rough2 = part->rough2;
686         float rough_end = part->rough_end;
687         const bool smooth_start = (sim->psys->part->childtype == PART_CHILD_FACES);
688
689         if (ptex) {
690                 kink_amp *= ptex->kink_amp;
691                 kink_freq *= ptex->kink_freq;
692                 rough1 *= ptex->rough1;
693                 rough2 *= ptex->rough2;
694                 rough_end *= ptex->roughe;
695         }
696
697         if (part->flag & PART_CHILD_EFFECT)
698                 /* state is safe to cast, since only co and vel are used */
699                 guided = do_guides(sim->eval_ctx, sim->psys->part, sim->psys->effectors, (ParticleKey *)state, cpa->parent, t);
700
701         if (guided == 0) {
702                 float orco_offset[3];
703                 float clump;
704
705                 sub_v3_v3v3(orco_offset, orco, par_orco);
706                 clump = do_clump(state, par_co, t, orco_offset, part->clumpfac, part->clumppow, ptex ? ptex->clump : 1.f,
707                                  part->child_flag & PART_CHILD_USE_CLUMP_NOISE, part->clump_noise_size, clumpcurve);
708
709                 if (kink_freq != 0.f) {
710                         kink_amp *= (1.f - kink_amp_clump * clump);
711
712                         do_kink(state, par_co, par_vel, par_rot, t, kink_freq, part->kink_shape,
713                                 kink_amp, part->kink_flat, part->kink, part->kink_axis,
714                                 sim->ob->obmat, smooth_start);
715                 }
716         }
717
718         if (roughcurve) {
719                 do_rough_curve(orco, mat, t, rough1, part->rough1_size, roughcurve, state);
720         }
721         else {
722                 if (rough1 > 0.f)
723                         do_rough(orco, mat, t, rough1, part->rough1_size, 0.0, state);
724
725                 if (rough2 > 0.f) {
726                         float vec[3];
727                         psys_frand_vec(sim->psys, i + 27, vec);
728                         do_rough(vec, mat, t, rough2, part->rough2_size, part->rough2_thres, state);
729                 }
730
731                 if (rough_end > 0.f) {
732                         float vec[3];
733                         psys_frand_vec(sim->psys, i + 27, vec);
734                         do_rough_end(vec, mat, t, rough_end, part->rough_end_shape, state);
735                 }
736         }
737 }