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