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