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                 printf("%f\n", ptex->twist);
362                 for (k = 0, key = keys; k < totkeys; k++, key++) {
363                         ParticlePathIterator iter;
364                         psys_path_iter_get(&iter, keys, totkeys, parent_keys, k);
365
366                         ParticleKey *par = (ParticleKey *)iter.parent_key;
367
368                         /* Fill in variant part of modifier context. */
369                         modifier_ctx.par_co = par->co;
370                         modifier_ctx.par_vel = par->vel;
371                         modifier_ctx.par_rot = iter.parent_rotation;
372                         modifier_ctx.par_orco = parent_orco;
373
374                         /* Apply different deformations to the child path. */
375                         do_child_modifiers(&modifier_ctx, hairmat, (ParticleKey *)key, iter.time);
376                 }
377         }
378
379         {
380                 const float step_length = 1.0f / (float)(totkeys - 1);
381                 float cur_length = 0.0f;
382
383                 if (max_length <= 0.0f) {
384                         keys->segments = -1;
385                         totkeys = 0;
386                 }
387
388                 /* we have to correct velocity because of kink & clump */
389                 for (k = 0, key = keys; k < totkeys; ++k, ++key) {
390                         if (k >= 2) {
391                                 sub_v3_v3v3((key-1)->vel, key->co, (key-2)->co);
392                                 mul_v3_fl((key-1)->vel, 0.5);
393
394                                 if (ma && draw_col_ma)
395                                         get_strand_normal(ma, ornor, cur_length, (key-1)->vel);
396                         }
397
398                         if (use_length_check && k > 1) {
399                                 float dvec[3];
400                                 /* check if path needs to be cut before actual end of data points */
401                                 if (!check_path_length(k, keys, key, max_length, step_length, &cur_length, dvec)) {
402                                         /* last key */
403                                         sub_v3_v3v3(key->vel, key->co, (key-1)->co);
404                                         if (ma && draw_col_ma) {
405                                                 copy_v3_v3(key->col, &ma->r);
406                                         }
407                                         break;
408                                 }
409                         }
410                         if (k == totkeys-1) {
411                                 /* last key */
412                                 sub_v3_v3v3(key->vel, key->co, (key-1)->co);
413                         }
414
415                         if (ma && draw_col_ma) {
416                                 copy_v3_v3(key->col, &ma->r);
417                                 get_strand_normal(ma, ornor, cur_length, key->vel);
418                         }
419                 }
420         }
421 #endif
422 }
423
424 /* ------------------------------------------------------------------------- */
425
426 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,
427              float amplitude, float flat, short type, short axis, float obmat[4][4], int smooth_start)
428 {
429         float kink[3] = {1.f, 0.f, 0.f}, par_vec[3], q1[4] = {1.f, 0.f, 0.f, 0.f};
430         float t, dt = 1.f, result[3];
431
432         if (ELEM(type, PART_KINK_NO, PART_KINK_SPIRAL))
433                 return;
434
435         CLAMP(time, 0.f, 1.f);
436
437         if (shape != 0.0f && !ELEM(type, PART_KINK_BRAID)) {
438                 if (shape < 0.0f)
439                         time = (float)pow(time, 1.f + shape);
440                 else
441                         time = (float)pow(time, 1.f / (1.f - shape));
442         }
443
444         t = time * freq * (float)M_PI;
445
446         if (smooth_start) {
447                 dt = fabsf(t);
448                 /* smooth the beginning of kink */
449                 CLAMP(dt, 0.f, (float)M_PI);
450                 dt = sinf(dt / 2.f);
451         }
452
453         if (!ELEM(type, PART_KINK_RADIAL)) {
454                 float temp[3];
455
456                 kink[axis] = 1.f;
457
458                 if (obmat)
459                         mul_mat3_m4_v3(obmat, kink);
460
461                 mul_qt_v3(par_rot, kink);
462
463                 /* make sure kink is normal to strand */
464                 project_v3_v3v3(temp, kink, par_vel);
465                 sub_v3_v3(kink, temp);
466                 normalize_v3(kink);
467         }
468
469         copy_v3_v3(result, state->co);
470         sub_v3_v3v3(par_vec, par_co, state->co);
471
472         switch (type) {
473                 case PART_KINK_CURL:
474                 {
475                         float curl_offset[3];
476
477                         /* rotate kink vector around strand tangent */
478                         mul_v3_v3fl(curl_offset, kink, amplitude);
479                         axis_angle_to_quat(q1, par_vel, t);
480                         mul_qt_v3(q1, curl_offset);
481
482                         interp_v3_v3v3(par_vec, state->co, par_co, flat);
483                         add_v3_v3v3(result, par_vec, curl_offset);
484                         break;
485                 }
486                 case PART_KINK_RADIAL:
487                 {
488                         if (flat > 0.f) {
489                                 float proj[3];
490                                 /* flatten along strand */
491                                 project_v3_v3v3(proj, par_vec, par_vel);
492                                 madd_v3_v3fl(result, proj, flat);
493                         }
494
495                         madd_v3_v3fl(result, par_vec, -amplitude * sinf(t));
496                         break;
497                 }
498                 case PART_KINK_WAVE:
499                 {
500                         madd_v3_v3fl(result, kink, amplitude * sinf(t));
501
502                         if (flat > 0.f) {
503                                 float proj[3];
504                                 /* flatten along wave */
505                                 project_v3_v3v3(proj, par_vec, kink);
506                                 madd_v3_v3fl(result, proj, flat);
507
508                                 /* flatten along strand */
509                                 project_v3_v3v3(proj, par_vec, par_vel);
510                                 madd_v3_v3fl(result, proj, flat);
511                         }
512                         break;
513                 }
514                 case PART_KINK_BRAID:
515                 {
516                         float y_vec[3] = {0.f, 1.f, 0.f};
517                         float z_vec[3] = {0.f, 0.f, 1.f};
518                         float vec_one[3], state_co[3];
519                         float inp_y, inp_z, length;
520
521                         if (par_rot) {
522                                 mul_qt_v3(par_rot, y_vec);
523                                 mul_qt_v3(par_rot, z_vec);
524                         }
525
526                         negate_v3(par_vec);
527                         normalize_v3_v3(vec_one, par_vec);
528
529                         inp_y = dot_v3v3(y_vec, vec_one);
530                         inp_z = dot_v3v3(z_vec, vec_one);
531
532                         if (inp_y > 0.5f) {
533                                 copy_v3_v3(state_co, y_vec);
534
535                                 mul_v3_fl(y_vec, amplitude * cosf(t));
536                                 mul_v3_fl(z_vec, amplitude / 2.f * sinf(2.f * t));
537                         }
538                         else if (inp_z > 0.0f) {
539                                 mul_v3_v3fl(state_co, z_vec, sinf((float)M_PI / 3.f));
540                                 madd_v3_v3fl(state_co, y_vec, -0.5f);
541
542                                 mul_v3_fl(y_vec, -amplitude * cosf(t + (float)M_PI / 3.f));
543                                 mul_v3_fl(z_vec, amplitude / 2.f * cosf(2.f * t + (float)M_PI / 6.f));
544                         }
545                         else {
546                                 mul_v3_v3fl(state_co, z_vec, -sinf((float)M_PI / 3.f));
547                                 madd_v3_v3fl(state_co, y_vec, -0.5f);
548
549                                 mul_v3_fl(y_vec, amplitude * -sinf(t + (float)M_PI / 6.f));
550                                 mul_v3_fl(z_vec, amplitude / 2.f * -sinf(2.f * t + (float)M_PI / 3.f));
551                         }
552
553                         mul_v3_fl(state_co, amplitude);
554                         add_v3_v3(state_co, par_co);
555                         sub_v3_v3v3(par_vec, state->co, state_co);
556
557                         length = normalize_v3(par_vec);
558                         mul_v3_fl(par_vec, MIN2(length, amplitude / 2.f));
559
560                         add_v3_v3v3(state_co, par_co, y_vec);
561                         add_v3_v3(state_co, z_vec);
562                         add_v3_v3(state_co, par_vec);
563
564                         shape = 2.f * (float)M_PI * (1.f + shape);
565
566                         if (t < shape) {
567                                 shape = t / shape;
568                                 shape = (float)sqrt((double)shape);
569                                 interp_v3_v3v3(result, result, state_co, shape);
570                         }
571                         else {
572                                 copy_v3_v3(result, state_co);
573                         }
574                         break;
575                 }
576         }
577
578         /* blend the start of the kink */
579         if (dt < 1.f)
580                 interp_v3_v3v3(state->co, state->co, result, dt);
581         else
582                 copy_v3_v3(state->co, result);
583 }
584
585 static float do_clump_level(float result[3], const float co[3], const float par_co[3], float time,
586                             float clumpfac, float clumppow, float pa_clump, CurveMapping *clumpcurve)
587 {
588         float clump = 0.0f;
589
590         if (clumpcurve) {
591                 clump = pa_clump * (1.0f - clamp_f(curvemapping_evaluateF(clumpcurve, 0, time), 0.0f, 1.0f));
592
593                 interp_v3_v3v3(result, co, par_co, clump);
594         }
595         else if (clumpfac != 0.0f) {
596                 float cpow;
597
598                 if (clumppow < 0.0f)
599                         cpow = 1.0f + clumppow;
600                 else
601                         cpow = 1.0f + 9.0f * clumppow;
602
603                 if (clumpfac < 0.0f) /* clump roots instead of tips */
604                         clump = -clumpfac * pa_clump * (float)pow(1.0 - (double)time, (double)cpow);
605                 else
606                         clump = clumpfac * pa_clump * (float)pow((double)time, (double)cpow);
607
608                 interp_v3_v3v3(result, co, par_co, clump);
609         }
610
611         return clump;
612 }
613
614 float do_clump(ParticleKey *state, const float par_co[3], float time, const float orco_offset[3], float clumpfac, float clumppow, float pa_clump,
615                bool use_clump_noise, float clump_noise_size, CurveMapping *clumpcurve)
616 {
617         float clump;
618
619         if (use_clump_noise && clump_noise_size != 0.0f) {
620                 float center[3], noisevec[3];
621                 float da[4], pa[12];
622
623                 mul_v3_v3fl(noisevec, orco_offset, 1.0f / clump_noise_size);
624                 voronoi(noisevec[0], noisevec[1], noisevec[2], da, pa, 1.0f, 0);
625                 mul_v3_fl(&pa[0], clump_noise_size);
626                 add_v3_v3v3(center, par_co, &pa[0]);
627
628                 do_clump_level(state->co, state->co, center, time, clumpfac, clumppow, pa_clump, clumpcurve);
629         }
630
631         clump = do_clump_level(state->co, state->co, par_co, time, clumpfac, clumppow, pa_clump, clumpcurve);
632
633         return clump;
634 }
635
636 static void do_rough(const float loc[3], float mat[4][4], float t, float fac, float size, float thres, ParticleKey *state)
637 {
638         float rough[3];
639         float rco[3];
640
641         if (thres != 0.0f) {
642                 if (fabsf((float)(-1.5f + loc[0] + loc[1] + loc[2])) < 1.5f * thres) {
643                         return;
644                 }
645         }
646
647         copy_v3_v3(rco, loc);
648         mul_v3_fl(rco, t);
649         rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2);
650         rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2);
651         rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2);
652
653         madd_v3_v3fl(state->co, mat[0], fac * rough[0]);
654         madd_v3_v3fl(state->co, mat[1], fac * rough[1]);
655         madd_v3_v3fl(state->co, mat[2], fac * rough[2]);
656 }
657
658 static void do_rough_end(const float loc[3], float mat[4][4], float t, float fac, float shape, ParticleKey *state)
659 {
660         float rough[2];
661         float roughfac;
662
663         roughfac = fac * (float)pow((double)t, shape);
664         copy_v2_v2(rough, loc);
665         rough[0] = -1.0f + 2.0f * rough[0];
666         rough[1] = -1.0f + 2.0f * rough[1];
667         mul_v2_fl(rough, roughfac);
668
669         madd_v3_v3fl(state->co, mat[0], rough[0]);
670         madd_v3_v3fl(state->co, mat[1], rough[1]);
671 }
672
673 static void do_rough_curve(const float loc[3], float mat[4][4], float time, float fac, float size, CurveMapping *roughcurve, ParticleKey *state)
674 {
675         float rough[3];
676         float rco[3];
677
678         if (!roughcurve)
679                 return;
680
681         fac *= clamp_f(curvemapping_evaluateF(roughcurve, 0, time), 0.0f, 1.0f);
682
683         copy_v3_v3(rco, loc);
684         mul_v3_fl(rco, time);
685         rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2);
686         rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2);
687         rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2);
688
689         madd_v3_v3fl(state->co, mat[0], fac * rough[0]);
690         madd_v3_v3fl(state->co, mat[1], fac * rough[1]);
691         madd_v3_v3fl(state->co, mat[2], fac * rough[2]);
692 }
693
694 static int twist_num_segments(const ParticleChildModifierContext *modifier_ctx)
695 {
696         ParticleThreadContext *thread_ctx = modifier_ctx->thread_ctx;
697         return (thread_ctx != NULL) ? thread_ctx->segments
698                                     : modifier_ctx->sim->psys->part->draw_step;
699 }
700
701 static void twist_get_axis(const ParticleChildModifierContext *modifier_ctx,
702                            const float time, float r_axis[3])
703 {
704         const int num_segments = twist_num_segments(modifier_ctx);
705         const int index = clamp_i(time * num_segments, 0, num_segments);
706         if (index > 0) {
707                 sub_v3_v3v3(r_axis,
708                             modifier_ctx->parent_keys[index].co,
709                             modifier_ctx->parent_keys[index - 1].co);
710         }
711         else {
712                 sub_v3_v3v3(r_axis,
713                             modifier_ctx->parent_keys[index + 1].co,
714                             modifier_ctx->parent_keys[index].co);
715         }
716 }
717
718 static float curvemapping_integrate_clamped(CurveMapping *curve,
719                                             float start, float end, float step)
720 {
721         float integral = 0.0f;
722         float x = start;
723         while (x < end) {
724                 float y = curvemapping_evaluateF(curve, 0, x);
725                 y = clamp_f(y, 0.0f, 1.0f);
726                 /* TODO(sergey): Clamp last step to end. */
727                 integral += y * step;
728                 x += step;
729         }
730         return integral;
731 }
732
733 static void do_twist(const ParticleChildModifierContext *modifier_ctx,
734                      ParticleKey *state, const float time)
735 {
736         ParticleThreadContext *thread_ctx = modifier_ctx->thread_ctx;
737         ParticleSimulationData *sim = modifier_ctx->sim;
738         ParticleTexture *ptex = modifier_ctx->ptex;
739         ParticleSettings *part = sim->psys->part;
740         /* Early output checks. */
741         if (part->childtype != PART_CHILD_PARTICLES) {
742                 /* Interpolated children behave weird with twist. */
743                 return;
744         }
745         if (part->twist == 0.0f) {
746                 /* No twist along the strand.  */
747                 return;
748         }
749         /* Dependent on whether it's threaded update or not, curve comes
750          * from different places.
751          */
752         CurveMapping *twist_curve = NULL;
753         if (part->child_flag & PART_CHILD_USE_TWIST_CURVE) {
754                 twist_curve = (thread_ctx != NULL) ? thread_ctx->twistcurve
755                                                    : part->twistcurve;
756         }
757         /* Axis of rotation. */
758         float axis[3];
759         twist_get_axis(modifier_ctx, time, axis);
760         /* Angle of rotation. */
761         float angle = part->twist;
762         if (ptex != NULL) {
763                 angle *= (ptex->twist - 0.5f) * 2.0f;
764         }
765         if (twist_curve != NULL) {
766                 const int num_segments = twist_num_segments(modifier_ctx);
767                 angle *= curvemapping_integrate_clamped(twist_curve,
768                                                         0.0f, time,
769                                                         1.0f / num_segments);
770         }
771         else {
772                 angle *= time;
773         }
774         /* Perform rotation around parent curve. */
775         float vec[3];
776         sub_v3_v3v3(vec, state->co, modifier_ctx->par_co);
777         rotate_v3_v3v3fl(state->co, vec, axis, angle * 2.0f * M_PI);
778         add_v3_v3(state->co, modifier_ctx->par_co);
779 }
780
781 void do_child_modifiers(const ParticleChildModifierContext *modifier_ctx,
782                         float mat[4][4], ParticleKey *state, float t)
783 {
784         ParticleThreadContext *ctx = modifier_ctx->thread_ctx;
785         ParticleSimulationData *sim = modifier_ctx->sim;
786         ParticleTexture *ptex = modifier_ctx->ptex;
787         ChildParticle *cpa = modifier_ctx->cpa;
788         ParticleSettings *part = sim->psys->part;
789         CurveMapping *clumpcurve = NULL, *roughcurve = NULL;
790         int i = cpa - sim->psys->child;
791         int guided = 0;
792
793         if (part->child_flag & PART_CHILD_USE_CLUMP_CURVE) {
794                 clumpcurve = (ctx != NULL) ? ctx->clumpcurve : part->clumpcurve;
795         }
796         if (part->child_flag & PART_CHILD_USE_ROUGH_CURVE) {
797                 roughcurve = (ctx != NULL) ? ctx->roughcurve : part->roughcurve;
798         }
799
800         float kink_amp = part->kink_amp;
801         float kink_amp_clump = part->kink_amp_clump;
802         float kink_freq = part->kink_freq;
803         float rough1 = part->rough1;
804         float rough2 = part->rough2;
805         float rough_end = part->rough_end;
806         const bool smooth_start = (sim->psys->part->childtype == PART_CHILD_FACES);
807
808         if (ptex) {
809                 kink_amp *= ptex->kink_amp;
810                 kink_freq *= ptex->kink_freq;
811                 rough1 *= ptex->rough1;
812                 rough2 *= ptex->rough2;
813                 rough_end *= ptex->roughe;
814         }
815
816         do_twist(modifier_ctx, state, t);
817
818         if (part->flag & PART_CHILD_EFFECT)
819                 /* state is safe to cast, since only co and vel are used */
820                 guided = do_guides(sim->eval_ctx, sim->psys->part, sim->psys->effectors, (ParticleKey *)state, cpa->parent, t);
821
822         if (guided == 0) {
823                 float orco_offset[3];
824                 float clump;
825
826                 sub_v3_v3v3(orco_offset, modifier_ctx->orco, modifier_ctx->par_orco);
827                 clump = do_clump(state,
828                                  modifier_ctx->par_co,
829                                  t,
830                                  orco_offset,
831                                  part->clumpfac,
832                                  part->clumppow,
833                                  ptex ? ptex->clump : 1.0f,
834                                  part->child_flag & PART_CHILD_USE_CLUMP_NOISE,
835                                  part->clump_noise_size,
836                                  clumpcurve);
837
838                 if (kink_freq != 0.f) {
839                         kink_amp *= (1.f - kink_amp_clump * clump);
840
841                         do_kink(state,
842                                 modifier_ctx->par_co,
843                                 modifier_ctx->par_vel,
844                                 modifier_ctx->par_rot,
845                                 t,
846                                 kink_freq,
847                                 part->kink_shape,
848                                 kink_amp,
849                                 part->kink_flat,
850                                 part->kink,
851                                 part->kink_axis,
852                                 sim->ob->obmat,
853                                 smooth_start);
854                 }
855         }
856
857         if (roughcurve) {
858                 do_rough_curve(modifier_ctx->orco, mat, t, rough1, part->rough1_size, roughcurve, state);
859         }
860         else {
861                 if (rough1 > 0.f)
862                         do_rough(modifier_ctx->orco, mat, t, rough1, part->rough1_size, 0.0, state);
863
864                 if (rough2 > 0.f) {
865                         float vec[3];
866                         psys_frand_vec(sim->psys, i + 27, vec);
867                         do_rough(vec, mat, t, rough2, part->rough2_size, part->rough2_thres, state);
868                 }
869
870                 if (rough_end > 0.f) {
871                         float vec[3];
872                         psys_frand_vec(sim->psys, i + 27, vec);
873                         do_rough_end(vec, mat, t, rough_end, part->rough_end_shape, state);
874                 }
875         }
876 }