Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenkernel / intern / particle_child.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) Blender Foundation
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Lukas Toenne
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/blenkernel/intern/particle_child.c
29  *  \ingroup bke
30  */
31
32 #include "BLI_math.h"
33 #include "BLI_noise.h"
34
35 #include "DNA_material_types.h"
36
37 #include "BKE_colortools.h"
38 #include "BKE_particle.h"
39
40 #include "particle_private.h"
41
42 /* ------------------------------------------------------------------------- */
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 #if 0 /* TODO for the future: use true particle modifiers that work on the whole curve */
303         for (mod = modifiers->first; mod; mod = mod->next) {
304                 mod->apply(keys, totkeys, parent_keys);
305         }
306 #else
307         (void)modifiers;
308         (void)mod;
309
310         if (part->kink == PART_KINK_SPIRAL) {
311                 do_kink_spiral(ctx, ptex, parent_orco, cpa, orco, hairmat, keys, parent_keys, &totkeys, &max_length);
312                 keys->segments = totkeys - 1;
313         }
314         else {
315                 /* Fill in invariant part of modifier context. */
316                 ParticleChildModifierContext modifier_ctx = {NULL};
317                 modifier_ctx.thread_ctx = ctx;
318                 modifier_ctx.sim = &ctx->sim;
319                 modifier_ctx.ptex = ptex;
320                 modifier_ctx.cpa = cpa;
321                 modifier_ctx.orco = orco;
322                 modifier_ctx.parent_keys = parent_keys;
323
324                 totkeys = ctx->segments + 1;
325                 max_length = ptex->length;
326
327                 for (k = 0, key = keys; k < totkeys; k++, key++) {
328                         ParticlePathIterator iter;
329                         psys_path_iter_get(&iter, keys, totkeys, parent_keys, k);
330
331                         ParticleKey *par = (ParticleKey *)iter.parent_key;
332
333                         /* Fill in variant part of modifier context. */
334                         modifier_ctx.par_co = par->co;
335                         modifier_ctx.par_vel = par->vel;
336                         modifier_ctx.par_rot = iter.parent_rotation;
337                         modifier_ctx.par_orco = parent_orco;
338
339                         /* Apply different deformations to the child path. */
340                         do_child_modifiers(&modifier_ctx, hairmat, (ParticleKey *)key, iter.time);
341                 }
342         }
343
344         {
345                 const float step_length = 1.0f / (float)(totkeys - 1);
346                 float cur_length = 0.0f;
347
348                 if (max_length <= 0.0f) {
349                         keys->segments = -1;
350                         totkeys = 0;
351                 }
352
353                 /* we have to correct velocity because of kink & clump */
354                 for (k = 0, key = keys; k < totkeys; ++k, ++key) {
355                         if (k >= 2) {
356                                 sub_v3_v3v3((key-1)->vel, key->co, (key-2)->co);
357                                 mul_v3_fl((key-1)->vel, 0.5);
358                         }
359
360                         if (use_length_check && k > 0) {
361                                 float dvec[3];
362                                 /* check if path needs to be cut before actual end of data points */
363                                 if (!check_path_length(k, keys, key, max_length, step_length, &cur_length, dvec)) {
364                                         /* last key */
365                                         sub_v3_v3v3(key->vel, key->co, (key-1)->co);
366                                         if (ma && draw_col_ma) {
367                                                 copy_v3_v3(key->col, &ma->r);
368                                         }
369                                         break;
370                                 }
371                         }
372                         if (k == totkeys-1) {
373                                 /* last key */
374                                 sub_v3_v3v3(key->vel, key->co, (key-1)->co);
375                         }
376
377                         if (ma && draw_col_ma) {
378                                 copy_v3_v3(key->col, &ma->r);
379                         }
380                 }
381         }
382 #endif
383 }
384
385 /* ------------------------------------------------------------------------- */
386
387 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,
388              float amplitude, float flat, short type, short axis, float obmat[4][4], int smooth_start)
389 {
390         float kink[3] = {1.f, 0.f, 0.f}, par_vec[3], q1[4] = {1.f, 0.f, 0.f, 0.f};
391         float t, dt = 1.f, result[3];
392
393         if (ELEM(type, PART_KINK_NO, PART_KINK_SPIRAL))
394                 return;
395
396         CLAMP(time, 0.f, 1.f);
397
398         if (shape != 0.0f && !ELEM(type, PART_KINK_BRAID)) {
399                 if (shape < 0.0f)
400                         time = (float)pow(time, 1.f + shape);
401                 else
402                         time = (float)pow(time, 1.f / (1.f - shape));
403         }
404
405         t = time * freq * (float)M_PI;
406
407         if (smooth_start) {
408                 dt = fabsf(t);
409                 /* smooth the beginning of kink */
410                 CLAMP(dt, 0.f, (float)M_PI);
411                 dt = sinf(dt / 2.f);
412         }
413
414         if (!ELEM(type, PART_KINK_RADIAL)) {
415                 float temp[3];
416
417                 kink[axis] = 1.f;
418
419                 if (obmat)
420                         mul_mat3_m4_v3(obmat, kink);
421
422                 mul_qt_v3(par_rot, kink);
423
424                 /* make sure kink is normal to strand */
425                 project_v3_v3v3(temp, kink, par_vel);
426                 sub_v3_v3(kink, temp);
427                 normalize_v3(kink);
428         }
429
430         copy_v3_v3(result, state->co);
431         sub_v3_v3v3(par_vec, par_co, state->co);
432
433         switch (type) {
434                 case PART_KINK_CURL:
435                 {
436                         float curl_offset[3];
437
438                         /* rotate kink vector around strand tangent */
439                         mul_v3_v3fl(curl_offset, kink, amplitude);
440                         axis_angle_to_quat(q1, par_vel, t);
441                         mul_qt_v3(q1, curl_offset);
442
443                         interp_v3_v3v3(par_vec, state->co, par_co, flat);
444                         add_v3_v3v3(result, par_vec, curl_offset);
445                         break;
446                 }
447                 case PART_KINK_RADIAL:
448                 {
449                         if (flat > 0.f) {
450                                 float proj[3];
451                                 /* flatten along strand */
452                                 project_v3_v3v3(proj, par_vec, par_vel);
453                                 madd_v3_v3fl(result, proj, flat);
454                         }
455
456                         madd_v3_v3fl(result, par_vec, -amplitude * sinf(t));
457                         break;
458                 }
459                 case PART_KINK_WAVE:
460                 {
461                         madd_v3_v3fl(result, kink, amplitude * sinf(t));
462
463                         if (flat > 0.f) {
464                                 float proj[3];
465                                 /* flatten along wave */
466                                 project_v3_v3v3(proj, par_vec, kink);
467                                 madd_v3_v3fl(result, proj, flat);
468
469                                 /* flatten along strand */
470                                 project_v3_v3v3(proj, par_vec, par_vel);
471                                 madd_v3_v3fl(result, proj, flat);
472                         }
473                         break;
474                 }
475                 case PART_KINK_BRAID:
476                 {
477                         float y_vec[3] = {0.f, 1.f, 0.f};
478                         float z_vec[3] = {0.f, 0.f, 1.f};
479                         float vec_one[3], state_co[3];
480                         float inp_y, inp_z, length;
481
482                         if (par_rot) {
483                                 mul_qt_v3(par_rot, y_vec);
484                                 mul_qt_v3(par_rot, z_vec);
485                         }
486
487                         negate_v3(par_vec);
488                         normalize_v3_v3(vec_one, par_vec);
489
490                         inp_y = dot_v3v3(y_vec, vec_one);
491                         inp_z = dot_v3v3(z_vec, vec_one);
492
493                         if (inp_y > 0.5f) {
494                                 copy_v3_v3(state_co, y_vec);
495
496                                 mul_v3_fl(y_vec, amplitude * cosf(t));
497                                 mul_v3_fl(z_vec, amplitude / 2.f * sinf(2.f * t));
498                         }
499                         else if (inp_z > 0.0f) {
500                                 mul_v3_v3fl(state_co, z_vec, sinf((float)M_PI / 3.f));
501                                 madd_v3_v3fl(state_co, y_vec, -0.5f);
502
503                                 mul_v3_fl(y_vec, -amplitude * cosf(t + (float)M_PI / 3.f));
504                                 mul_v3_fl(z_vec, amplitude / 2.f * cosf(2.f * t + (float)M_PI / 6.f));
505                         }
506                         else {
507                                 mul_v3_v3fl(state_co, z_vec, -sinf((float)M_PI / 3.f));
508                                 madd_v3_v3fl(state_co, y_vec, -0.5f);
509
510                                 mul_v3_fl(y_vec, amplitude * -sinf(t + (float)M_PI / 6.f));
511                                 mul_v3_fl(z_vec, amplitude / 2.f * -sinf(2.f * t + (float)M_PI / 3.f));
512                         }
513
514                         mul_v3_fl(state_co, amplitude);
515                         add_v3_v3(state_co, par_co);
516                         sub_v3_v3v3(par_vec, state->co, state_co);
517
518                         length = normalize_v3(par_vec);
519                         mul_v3_fl(par_vec, MIN2(length, amplitude / 2.f));
520
521                         add_v3_v3v3(state_co, par_co, y_vec);
522                         add_v3_v3(state_co, z_vec);
523                         add_v3_v3(state_co, par_vec);
524
525                         shape = 2.f * (float)M_PI * (1.f + shape);
526
527                         if (t < shape) {
528                                 shape = t / shape;
529                                 shape = (float)sqrt((double)shape);
530                                 interp_v3_v3v3(result, result, state_co, shape);
531                         }
532                         else {
533                                 copy_v3_v3(result, state_co);
534                         }
535                         break;
536                 }
537         }
538
539         /* blend the start of the kink */
540         if (dt < 1.f)
541                 interp_v3_v3v3(state->co, state->co, result, dt);
542         else
543                 copy_v3_v3(state->co, result);
544 }
545
546 static float do_clump_level(float result[3], const float co[3], const float par_co[3], float time,
547                             float clumpfac, float clumppow, float pa_clump, CurveMapping *clumpcurve)
548 {
549         float clump = 0.0f;
550
551         if (clumpcurve) {
552                 clump = pa_clump * (1.0f - clamp_f(curvemapping_evaluateF(clumpcurve, 0, time), 0.0f, 1.0f));
553
554                 interp_v3_v3v3(result, co, par_co, clump);
555         }
556         else if (clumpfac != 0.0f) {
557                 float cpow;
558
559                 if (clumppow < 0.0f)
560                         cpow = 1.0f + clumppow;
561                 else
562                         cpow = 1.0f + 9.0f * clumppow;
563
564                 if (clumpfac < 0.0f) /* clump roots instead of tips */
565                         clump = -clumpfac * pa_clump * (float)pow(1.0 - (double)time, (double)cpow);
566                 else
567                         clump = clumpfac * pa_clump * (float)pow((double)time, (double)cpow);
568
569                 interp_v3_v3v3(result, co, par_co, clump);
570         }
571
572         return clump;
573 }
574
575 float do_clump(ParticleKey *state, const float par_co[3], float time, const float orco_offset[3], float clumpfac, float clumppow, float pa_clump,
576                bool use_clump_noise, float clump_noise_size, CurveMapping *clumpcurve)
577 {
578         float clump;
579
580         if (use_clump_noise && clump_noise_size != 0.0f) {
581                 float center[3], noisevec[3];
582                 float da[4], pa[12];
583
584                 mul_v3_v3fl(noisevec, orco_offset, 1.0f / clump_noise_size);
585                 voronoi(noisevec[0], noisevec[1], noisevec[2], da, pa, 1.0f, 0);
586                 mul_v3_fl(&pa[0], clump_noise_size);
587                 add_v3_v3v3(center, par_co, &pa[0]);
588
589                 do_clump_level(state->co, state->co, center, time, clumpfac, clumppow, pa_clump, clumpcurve);
590         }
591
592         clump = do_clump_level(state->co, state->co, par_co, time, clumpfac, clumppow, pa_clump, clumpcurve);
593
594         return clump;
595 }
596
597 static void do_rough(const float loc[3], float mat[4][4], float t, float fac, float size, float thres, ParticleKey *state)
598 {
599         float rough[3];
600         float rco[3];
601
602         if (thres != 0.0f) {
603                 if (fabsf((float)(-1.5f + loc[0] + loc[1] + loc[2])) < 1.5f * thres) {
604                         return;
605                 }
606         }
607
608         copy_v3_v3(rco, loc);
609         mul_v3_fl(rco, t);
610         rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2);
611         rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2);
612         rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2);
613
614         madd_v3_v3fl(state->co, mat[0], fac * rough[0]);
615         madd_v3_v3fl(state->co, mat[1], fac * rough[1]);
616         madd_v3_v3fl(state->co, mat[2], fac * rough[2]);
617 }
618
619 static void do_rough_end(const float loc[3], float mat[4][4], float t, float fac, float shape, ParticleKey *state)
620 {
621         float rough[2];
622         float roughfac;
623
624         roughfac = fac * (float)pow((double)t, shape);
625         copy_v2_v2(rough, loc);
626         rough[0] = -1.0f + 2.0f * rough[0];
627         rough[1] = -1.0f + 2.0f * rough[1];
628         mul_v2_fl(rough, roughfac);
629
630         madd_v3_v3fl(state->co, mat[0], rough[0]);
631         madd_v3_v3fl(state->co, mat[1], rough[1]);
632 }
633
634 static void do_rough_curve(const float loc[3], float mat[4][4], float time, float fac, float size, CurveMapping *roughcurve, ParticleKey *state)
635 {
636         float rough[3];
637         float rco[3];
638
639         if (!roughcurve)
640                 return;
641
642         fac *= clamp_f(curvemapping_evaluateF(roughcurve, 0, time), 0.0f, 1.0f);
643
644         copy_v3_v3(rco, loc);
645         mul_v3_fl(rco, time);
646         rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2);
647         rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2);
648         rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2);
649
650         madd_v3_v3fl(state->co, mat[0], fac * rough[0]);
651         madd_v3_v3fl(state->co, mat[1], fac * rough[1]);
652         madd_v3_v3fl(state->co, mat[2], fac * rough[2]);
653 }
654
655 static int twist_num_segments(const ParticleChildModifierContext *modifier_ctx)
656 {
657         ParticleThreadContext *thread_ctx = modifier_ctx->thread_ctx;
658         return (thread_ctx != NULL) ? thread_ctx->segments
659                                     : modifier_ctx->sim->psys->part->draw_step;
660 }
661
662 static void twist_get_axis(const ParticleChildModifierContext *modifier_ctx,
663                            const float time, float r_axis[3])
664 {
665         const int num_segments = twist_num_segments(modifier_ctx);
666         const int index = clamp_i(time * num_segments, 0, num_segments);
667         if (index > 0) {
668                 sub_v3_v3v3(r_axis,
669                             modifier_ctx->parent_keys[index].co,
670                             modifier_ctx->parent_keys[index - 1].co);
671         }
672         else {
673                 sub_v3_v3v3(r_axis,
674                             modifier_ctx->parent_keys[index + 1].co,
675                             modifier_ctx->parent_keys[index].co);
676         }
677 }
678
679 static float curvemapping_integrate_clamped(CurveMapping *curve,
680                                             float start, float end, float step)
681 {
682         float integral = 0.0f;
683         float x = start;
684         while (x < end) {
685                 float y = curvemapping_evaluateF(curve, 0, x);
686                 y = clamp_f(y, 0.0f, 1.0f);
687                 /* TODO(sergey): Clamp last step to end. */
688                 integral += y * step;
689                 x += step;
690         }
691         return integral;
692 }
693
694 static void do_twist(const ParticleChildModifierContext *modifier_ctx,
695                      ParticleKey *state, const float time)
696 {
697         ParticleThreadContext *thread_ctx = modifier_ctx->thread_ctx;
698         ParticleSimulationData *sim = modifier_ctx->sim;
699         ParticleTexture *ptex = modifier_ctx->ptex;
700         ParticleSettings *part = sim->psys->part;
701         /* Early output checks. */
702         if (part->childtype != PART_CHILD_PARTICLES) {
703                 /* Interpolated children behave weird with twist. */
704                 return;
705         }
706         if (part->twist == 0.0f) {
707                 /* No twist along the strand.  */
708                 return;
709         }
710         /* Dependent on whether it's threaded update or not, curve comes
711          * from different places.
712          */
713         CurveMapping *twist_curve = NULL;
714         if (part->child_flag & PART_CHILD_USE_TWIST_CURVE) {
715                 twist_curve = (thread_ctx != NULL) ? thread_ctx->twistcurve
716                                                    : part->twistcurve;
717         }
718         /* Axis of rotation. */
719         float axis[3];
720         twist_get_axis(modifier_ctx, time, axis);
721         /* Angle of rotation. */
722         float angle = part->twist;
723         if (ptex != NULL) {
724                 angle *= (ptex->twist - 0.5f) * 2.0f;
725         }
726         if (twist_curve != NULL) {
727                 const int num_segments = twist_num_segments(modifier_ctx);
728                 angle *= curvemapping_integrate_clamped(twist_curve,
729                                                         0.0f, time,
730                                                         1.0f / num_segments);
731         }
732         else {
733                 angle *= time;
734         }
735         /* Perform rotation around parent curve. */
736         float vec[3];
737         sub_v3_v3v3(vec, state->co, modifier_ctx->par_co);
738         rotate_v3_v3v3fl(state->co, vec, axis, angle * 2.0f * M_PI);
739         add_v3_v3(state->co, modifier_ctx->par_co);
740 }
741
742 void do_child_modifiers(const ParticleChildModifierContext *modifier_ctx,
743                         float mat[4][4], ParticleKey *state, float t)
744 {
745         ParticleThreadContext *ctx = modifier_ctx->thread_ctx;
746         ParticleSimulationData *sim = modifier_ctx->sim;
747         ParticleTexture *ptex = modifier_ctx->ptex;
748         ChildParticle *cpa = modifier_ctx->cpa;
749         ParticleSettings *part = sim->psys->part;
750         CurveMapping *clumpcurve = NULL, *roughcurve = NULL;
751         int i = cpa - sim->psys->child;
752         int guided = 0;
753
754         if (part->child_flag & PART_CHILD_USE_CLUMP_CURVE) {
755                 clumpcurve = (ctx != NULL) ? ctx->clumpcurve : part->clumpcurve;
756         }
757         if (part->child_flag & PART_CHILD_USE_ROUGH_CURVE) {
758                 roughcurve = (ctx != NULL) ? ctx->roughcurve : part->roughcurve;
759         }
760
761         float kink_amp = part->kink_amp;
762         float kink_amp_clump = part->kink_amp_clump;
763         float kink_freq = part->kink_freq;
764         float rough1 = part->rough1;
765         float rough2 = part->rough2;
766         float rough_end = part->rough_end;
767         const bool smooth_start = (sim->psys->part->childtype == PART_CHILD_FACES);
768
769         if (ptex) {
770                 kink_amp *= ptex->kink_amp;
771                 kink_freq *= ptex->kink_freq;
772                 rough1 *= ptex->rough1;
773                 rough2 *= ptex->rough2;
774                 rough_end *= ptex->roughe;
775         }
776
777         do_twist(modifier_ctx, state, t);
778
779         if (part->flag & PART_CHILD_EFFECT)
780                 /* state is safe to cast, since only co and vel are used */
781                 guided = do_guides(sim->depsgraph, sim->psys->part, sim->psys->effectors, (ParticleKey *)state, cpa->parent, t);
782
783         if (guided == 0) {
784                 float orco_offset[3];
785                 float clump;
786
787                 sub_v3_v3v3(orco_offset, modifier_ctx->orco, modifier_ctx->par_orco);
788                 clump = do_clump(state,
789                                  modifier_ctx->par_co,
790                                  t,
791                                  orco_offset,
792                                  part->clumpfac,
793                                  part->clumppow,
794                                  ptex ? ptex->clump : 1.0f,
795                                  part->child_flag & PART_CHILD_USE_CLUMP_NOISE,
796                                  part->clump_noise_size,
797                                  clumpcurve);
798
799                 if (kink_freq != 0.f) {
800                         kink_amp *= (1.f - kink_amp_clump * clump);
801
802                         do_kink(state,
803                                 modifier_ctx->par_co,
804                                 modifier_ctx->par_vel,
805                                 modifier_ctx->par_rot,
806                                 t,
807                                 kink_freq,
808                                 part->kink_shape,
809                                 kink_amp,
810                                 part->kink_flat,
811                                 part->kink,
812                                 part->kink_axis,
813                                 sim->ob->obmat,
814                                 smooth_start);
815                 }
816         }
817
818         if (roughcurve) {
819                 do_rough_curve(modifier_ctx->orco, mat, t, rough1, part->rough1_size, roughcurve, state);
820         }
821         else {
822                 if (rough1 > 0.f)
823                         do_rough(modifier_ctx->orco, mat, t, rough1, part->rough1_size, 0.0, state);
824
825                 if (rough2 > 0.f) {
826                         float vec[3];
827                         psys_frand_vec(sim->psys, i + 27, vec);
828                         do_rough(vec, mat, t, rough2, part->rough2_size, part->rough2_thres, state);
829                 }
830
831                 if (rough_end > 0.f) {
832                         float vec[3];
833                         psys_frand_vec(sim->psys, i + 27, vec);
834                         do_rough_end(vec, mat, t, rough_end, part->rough_end_shape, state);
835                 }
836         }
837 }