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