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