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