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) 2007 by Janne Karhu.
17  * All rights reserved.
18  */
19 
20 /** \file
21  * \ingroup bke
22  */
23 
24 #include <math.h>
25 #include <stdlib.h>
26 #include <string.h>
27 
28 #include "MEM_guardedalloc.h"
29 
30 #include "DNA_defaults.h"
31 
32 #include "DNA_collection_types.h"
33 #include "DNA_curve_types.h"
34 #include "DNA_dynamicpaint_types.h"
35 #include "DNA_fluid_types.h"
36 #include "DNA_key_types.h"
37 #include "DNA_material_types.h"
38 #include "DNA_mesh_types.h"
39 #include "DNA_meshdata_types.h"
40 #include "DNA_particle_types.h"
41 #include "DNA_scene_types.h"
42 
43 #include "BLI_blenlib.h"
44 #include "BLI_kdopbvh.h"
45 #include "BLI_kdtree.h"
46 #include "BLI_linklist.h"
47 #include "BLI_math.h"
48 #include "BLI_rand.h"
49 #include "BLI_task.h"
50 #include "BLI_threads.h"
51 #include "BLI_utildefines.h"
52 
53 #include "BLT_translation.h"
54 
55 #include "BKE_anim_path.h"
56 #include "BKE_boids.h"
57 #include "BKE_cloth.h"
58 #include "BKE_collection.h"
59 #include "BKE_colortools.h"
60 #include "BKE_deform.h"
61 #include "BKE_displist.h"
62 #include "BKE_effect.h"
63 #include "BKE_idtype.h"
64 #include "BKE_key.h"
65 #include "BKE_lattice.h"
66 #include "BKE_lib_id.h"
67 #include "BKE_lib_query.h"
68 #include "BKE_main.h"
69 #include "BKE_material.h"
70 #include "BKE_mesh.h"
71 #include "BKE_modifier.h"
72 #include "BKE_particle.h"
73 #include "BKE_pointcache.h"
74 #include "BKE_scene.h"
75 #include "BKE_texture.h"
76 
77 #include "DEG_depsgraph.h"
78 #include "DEG_depsgraph_build.h"
79 #include "DEG_depsgraph_query.h"
80 
81 #include "RE_render_ext.h"
82 
83 #include "particle_private.h"
84 
85 static void fluid_free_settings(SPHFluidSettings *fluid);
86 
particle_settings_init(ID * id)87 static void particle_settings_init(ID *id)
88 {
89   ParticleSettings *particle_settings = (ParticleSettings *)id;
90   BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(particle_settings, id));
91 
92   MEMCPY_STRUCT_AFTER(particle_settings, DNA_struct_default_get(ParticleSettings), id);
93 
94   particle_settings->effector_weights = BKE_effector_add_weights(NULL);
95 }
96 
particle_settings_copy_data(Main * UNUSED (bmain),ID * id_dst,const ID * id_src,const int UNUSED (flag))97 static void particle_settings_copy_data(Main *UNUSED(bmain),
98                                         ID *id_dst,
99                                         const ID *id_src,
100                                         const int UNUSED(flag))
101 {
102   ParticleSettings *particle_settings_dst = (ParticleSettings *)id_dst;
103   const ParticleSettings *partticle_settings_src = (const ParticleSettings *)id_src;
104 
105   particle_settings_dst->pd = BKE_partdeflect_copy(partticle_settings_src->pd);
106   particle_settings_dst->pd2 = BKE_partdeflect_copy(partticle_settings_src->pd2);
107   particle_settings_dst->effector_weights = MEM_dupallocN(
108       partticle_settings_src->effector_weights);
109   particle_settings_dst->fluid = MEM_dupallocN(partticle_settings_src->fluid);
110 
111   if (partticle_settings_src->clumpcurve) {
112     particle_settings_dst->clumpcurve = BKE_curvemapping_copy(partticle_settings_src->clumpcurve);
113   }
114   if (partticle_settings_src->roughcurve) {
115     particle_settings_dst->roughcurve = BKE_curvemapping_copy(partticle_settings_src->roughcurve);
116   }
117   if (partticle_settings_src->twistcurve) {
118     particle_settings_dst->twistcurve = BKE_curvemapping_copy(partticle_settings_src->twistcurve);
119   }
120 
121   particle_settings_dst->boids = boid_copy_settings(partticle_settings_src->boids);
122 
123   for (int a = 0; a < MAX_MTEX; a++) {
124     if (partticle_settings_src->mtex[a]) {
125       particle_settings_dst->mtex[a] = MEM_dupallocN(partticle_settings_src->mtex[a]);
126     }
127   }
128 
129   BLI_duplicatelist(&particle_settings_dst->instance_weights,
130                     &partticle_settings_src->instance_weights);
131 }
132 
particle_settings_free_data(ID * id)133 static void particle_settings_free_data(ID *id)
134 {
135   ParticleSettings *particle_settings = (ParticleSettings *)id;
136 
137   for (int a = 0; a < MAX_MTEX; a++) {
138     MEM_SAFE_FREE(particle_settings->mtex[a]);
139   }
140 
141   if (particle_settings->clumpcurve) {
142     BKE_curvemapping_free(particle_settings->clumpcurve);
143   }
144   if (particle_settings->roughcurve) {
145     BKE_curvemapping_free(particle_settings->roughcurve);
146   }
147   if (particle_settings->twistcurve) {
148     BKE_curvemapping_free(particle_settings->twistcurve);
149   }
150 
151   BKE_partdeflect_free(particle_settings->pd);
152   BKE_partdeflect_free(particle_settings->pd2);
153 
154   MEM_SAFE_FREE(particle_settings->effector_weights);
155 
156   BLI_freelistN(&particle_settings->instance_weights);
157 
158   boid_free_settings(particle_settings->boids);
159   fluid_free_settings(particle_settings->fluid);
160 }
161 
particle_settings_foreach_id(ID * id,LibraryForeachIDData * data)162 static void particle_settings_foreach_id(ID *id, LibraryForeachIDData *data)
163 {
164   ParticleSettings *psett = (ParticleSettings *)id;
165   BKE_LIB_FOREACHID_PROCESS(data, psett->instance_collection, IDWALK_CB_USER);
166   BKE_LIB_FOREACHID_PROCESS(data, psett->instance_object, IDWALK_CB_NOP);
167   BKE_LIB_FOREACHID_PROCESS(data, psett->bb_ob, IDWALK_CB_NOP);
168   BKE_LIB_FOREACHID_PROCESS(data, psett->collision_group, IDWALK_CB_NOP);
169 
170   for (int i = 0; i < MAX_MTEX; i++) {
171     if (psett->mtex[i]) {
172       BKE_texture_mtex_foreach_id(data, psett->mtex[i]);
173     }
174   }
175 
176   if (psett->effector_weights) {
177     BKE_LIB_FOREACHID_PROCESS(data, psett->effector_weights->group, IDWALK_CB_NOP);
178   }
179 
180   if (psett->pd) {
181     BKE_LIB_FOREACHID_PROCESS(data, psett->pd->tex, IDWALK_CB_USER);
182     BKE_LIB_FOREACHID_PROCESS(data, psett->pd->f_source, IDWALK_CB_NOP);
183   }
184   if (psett->pd2) {
185     BKE_LIB_FOREACHID_PROCESS(data, psett->pd2->tex, IDWALK_CB_USER);
186     BKE_LIB_FOREACHID_PROCESS(data, psett->pd2->f_source, IDWALK_CB_NOP);
187   }
188 
189   if (psett->boids) {
190     LISTBASE_FOREACH (BoidState *, state, &psett->boids->states) {
191       LISTBASE_FOREACH (BoidRule *, rule, &state->rules) {
192         if (rule->type == eBoidRuleType_Avoid) {
193           BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid *)rule;
194           BKE_LIB_FOREACHID_PROCESS(data, gabr->ob, IDWALK_CB_NOP);
195         }
196         else if (rule->type == eBoidRuleType_FollowLeader) {
197           BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader *)rule;
198           BKE_LIB_FOREACHID_PROCESS(data, flbr->ob, IDWALK_CB_NOP);
199         }
200       }
201     }
202   }
203 
204   LISTBASE_FOREACH (ParticleDupliWeight *, dw, &psett->instance_weights) {
205     BKE_LIB_FOREACHID_PROCESS(data, dw->ob, IDWALK_CB_NOP);
206   }
207 }
208 
209 IDTypeInfo IDType_ID_PA = {
210     .id_code = ID_PA,
211     .id_filter = FILTER_ID_PA,
212     .main_listbase_index = INDEX_ID_PA,
213     .struct_size = sizeof(ParticleSettings),
214     .name = "ParticleSettings",
215     .name_plural = "particles",
216     .translation_context = BLT_I18NCONTEXT_ID_PARTICLESETTINGS,
217     .flags = 0,
218 
219     .init_data = particle_settings_init,
220     .copy_data = particle_settings_copy_data,
221     .free_data = particle_settings_free_data,
222     .make_local = NULL,
223     .foreach_id = particle_settings_foreach_id,
224     .foreach_cache = NULL,
225 
226     .blend_write = NULL,
227     .blend_read_data = NULL,
228     .blend_read_lib = NULL,
229     .blend_read_expand = NULL,
230 };
231 
232 unsigned int PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT];
233 unsigned int PSYS_FRAND_SEED_MULTIPLIER[PSYS_FRAND_COUNT];
234 float PSYS_FRAND_BASE[PSYS_FRAND_COUNT];
235 
psys_init_rng(void)236 void psys_init_rng(void)
237 {
238   RNG *rng = BLI_rng_new_srandom(5831); /* arbitrary */
239   for (int i = 0; i < PSYS_FRAND_COUNT; i++) {
240     PSYS_FRAND_BASE[i] = BLI_rng_get_float(rng);
241     PSYS_FRAND_SEED_OFFSET[i] = (unsigned int)BLI_rng_get_int(rng);
242     PSYS_FRAND_SEED_MULTIPLIER[i] = (unsigned int)BLI_rng_get_int(rng);
243   }
244   BLI_rng_free(rng);
245 }
246 
247 static void get_child_modifier_parameters(ParticleSettings *part,
248                                           ParticleThreadContext *ctx,
249                                           ChildParticle *cpa,
250                                           short cpa_from,
251                                           int cpa_num,
252                                           float *cpa_fuv,
253                                           float *orco,
254                                           ParticleTexture *ptex);
255 static void get_cpa_texture(Mesh *mesh,
256                             ParticleSystem *psys,
257                             ParticleSettings *part,
258                             ParticleData *par,
259                             int child_index,
260                             int face_index,
261                             const float fw[4],
262                             float *orco,
263                             ParticleTexture *ptex,
264                             int event,
265                             float cfra);
266 
267 /* few helpers for countall etc. */
count_particles(ParticleSystem * psys)268 int count_particles(ParticleSystem *psys)
269 {
270   ParticleSettings *part = psys->part;
271   PARTICLE_P;
272   int tot = 0;
273 
274   LOOP_SHOWN_PARTICLES
275   {
276     if (pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN) == 0) {
277     }
278     else if (pa->alive == PARS_DEAD && (part->flag & PART_DIED) == 0) {
279     }
280     else {
281       tot++;
282     }
283   }
284   return tot;
285 }
count_particles_mod(ParticleSystem * psys,int totgr,int cur)286 int count_particles_mod(ParticleSystem *psys, int totgr, int cur)
287 {
288   ParticleSettings *part = psys->part;
289   PARTICLE_P;
290   int tot = 0;
291 
292   LOOP_SHOWN_PARTICLES
293   {
294     if (pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN) == 0) {
295     }
296     else if (pa->alive == PARS_DEAD && (part->flag & PART_DIED) == 0) {
297     }
298     else if (p % totgr == cur) {
299       tot++;
300     }
301   }
302   return tot;
303 }
304 /* We allocate path cache memory in chunks instead of a big contiguous
305  * chunk, windows' memory allocator fails to find big blocks of memory often. */
306 
307 #define PATH_CACHE_BUF_SIZE 1024
308 
pcache_key_segment_endpoint_safe(ParticleCacheKey * key)309 static ParticleCacheKey *pcache_key_segment_endpoint_safe(ParticleCacheKey *key)
310 {
311   return (key->segments > 0) ? (key + (key->segments - 1)) : key;
312 }
313 
psys_alloc_path_cache_buffers(ListBase * bufs,int tot,int totkeys)314 static ParticleCacheKey **psys_alloc_path_cache_buffers(ListBase *bufs, int tot, int totkeys)
315 {
316   LinkData *buf;
317   ParticleCacheKey **cache;
318   int i, totkey, totbufkey;
319 
320   tot = MAX2(tot, 1);
321   totkey = 0;
322   cache = MEM_callocN(tot * sizeof(void *), "PathCacheArray");
323 
324   while (totkey < tot) {
325     totbufkey = MIN2(tot - totkey, PATH_CACHE_BUF_SIZE);
326     buf = MEM_callocN(sizeof(LinkData), "PathCacheLinkData");
327     buf->data = MEM_callocN(sizeof(ParticleCacheKey) * totbufkey * totkeys, "ParticleCacheKey");
328 
329     for (i = 0; i < totbufkey; i++) {
330       cache[totkey + i] = ((ParticleCacheKey *)buf->data) + i * totkeys;
331     }
332 
333     totkey += totbufkey;
334     BLI_addtail(bufs, buf);
335   }
336 
337   return cache;
338 }
339 
psys_free_path_cache_buffers(ParticleCacheKey ** cache,ListBase * bufs)340 static void psys_free_path_cache_buffers(ParticleCacheKey **cache, ListBase *bufs)
341 {
342   LinkData *buf;
343 
344   if (cache) {
345     MEM_freeN(cache);
346   }
347 
348   for (buf = bufs->first; buf; buf = buf->next) {
349     MEM_freeN(buf->data);
350   }
351   BLI_freelistN(bufs);
352 }
353 
354 /************************************************/
355 /*          Getting stuff                       */
356 /************************************************/
357 /* get object's active particle system safely */
psys_get_current(Object * ob)358 ParticleSystem *psys_get_current(Object *ob)
359 {
360   ParticleSystem *psys;
361   if (ob == NULL) {
362     return NULL;
363   }
364 
365   for (psys = ob->particlesystem.first; psys; psys = psys->next) {
366     if (psys->flag & PSYS_CURRENT) {
367       return psys;
368     }
369   }
370 
371   return NULL;
372 }
psys_get_current_num(Object * ob)373 short psys_get_current_num(Object *ob)
374 {
375   ParticleSystem *psys;
376   short i;
377 
378   if (ob == NULL) {
379     return 0;
380   }
381 
382   for (psys = ob->particlesystem.first, i = 0; psys; psys = psys->next, i++) {
383     if (psys->flag & PSYS_CURRENT) {
384       return i;
385     }
386   }
387 
388   return i;
389 }
psys_set_current_num(Object * ob,int index)390 void psys_set_current_num(Object *ob, int index)
391 {
392   ParticleSystem *psys;
393   short i;
394 
395   if (ob == NULL) {
396     return;
397   }
398 
399   for (psys = ob->particlesystem.first, i = 0; psys; psys = psys->next, i++) {
400     if (i == index) {
401       psys->flag |= PSYS_CURRENT;
402     }
403     else {
404       psys->flag &= ~PSYS_CURRENT;
405     }
406   }
407 }
408 
psys_create_lattice_deform_data(ParticleSimulationData * sim)409 struct LatticeDeformData *psys_create_lattice_deform_data(ParticleSimulationData *sim)
410 {
411   struct LatticeDeformData *lattice_deform_data = NULL;
412 
413   if (psys_in_edit_mode(sim->depsgraph, sim->psys) == 0) {
414     Object *lattice = NULL;
415     ModifierData *md = (ModifierData *)psys_get_modifier(sim->ob, sim->psys);
416     bool for_render = DEG_get_mode(sim->depsgraph) == DAG_EVAL_RENDER;
417     int mode = for_render ? eModifierMode_Render : eModifierMode_Realtime;
418 
419     for (; md; md = md->next) {
420       if (md->type == eModifierType_Lattice) {
421         if (md->mode & mode) {
422           LatticeModifierData *lmd = (LatticeModifierData *)md;
423           lattice = lmd->object;
424           sim->psys->lattice_strength = lmd->strength;
425         }
426 
427         break;
428       }
429     }
430     if (lattice) {
431       lattice_deform_data = BKE_lattice_deform_data_create(lattice, NULL);
432     }
433   }
434 
435   return lattice_deform_data;
436 }
psys_disable_all(Object * ob)437 void psys_disable_all(Object *ob)
438 {
439   ParticleSystem *psys = ob->particlesystem.first;
440 
441   for (; psys; psys = psys->next) {
442     psys->flag |= PSYS_DISABLED;
443   }
444 }
psys_enable_all(Object * ob)445 void psys_enable_all(Object *ob)
446 {
447   ParticleSystem *psys = ob->particlesystem.first;
448 
449   for (; psys; psys = psys->next) {
450     psys->flag &= ~PSYS_DISABLED;
451   }
452 }
453 
psys_orig_get(ParticleSystem * psys)454 ParticleSystem *psys_orig_get(ParticleSystem *psys)
455 {
456   if (psys->orig_psys == NULL) {
457     return psys;
458   }
459   return psys->orig_psys;
460 }
461 
psys_eval_get(Depsgraph * depsgraph,Object * object,ParticleSystem * psys)462 struct ParticleSystem *psys_eval_get(Depsgraph *depsgraph, Object *object, ParticleSystem *psys)
463 {
464   Object *object_eval = DEG_get_evaluated_object(depsgraph, object);
465   if (object_eval == object) {
466     return psys;
467   }
468   ParticleSystem *psys_eval = object_eval->particlesystem.first;
469   while (psys_eval != NULL) {
470     if (psys_eval->orig_psys == psys) {
471       return psys_eval;
472     }
473     psys_eval = psys_eval->next;
474   }
475   return psys_eval;
476 }
477 
psys_orig_edit_get(ParticleSystem * psys)478 static PTCacheEdit *psys_orig_edit_get(ParticleSystem *psys)
479 {
480   if (psys->orig_psys == NULL) {
481     return psys->edit;
482   }
483   return psys->orig_psys->edit;
484 }
485 
psys_in_edit_mode(Depsgraph * depsgraph,const ParticleSystem * psys)486 bool psys_in_edit_mode(Depsgraph *depsgraph, const ParticleSystem *psys)
487 {
488   const ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
489   if (view_layer->basact == NULL) {
490     /* TODO(sergey): Needs double-check with multi-object edit. */
491     return false;
492   }
493   const bool use_render_params = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
494   const Object *object = view_layer->basact->object;
495   if (object->mode != OB_MODE_PARTICLE_EDIT) {
496     return false;
497   }
498   const ParticleSystem *psys_orig = psys_orig_get((ParticleSystem *)psys);
499   return (psys_orig->edit || psys->pointcache->edit) && (use_render_params == false);
500 }
501 
psys_check_enabled(Object * ob,ParticleSystem * psys,const bool use_render_params)502 bool psys_check_enabled(Object *ob, ParticleSystem *psys, const bool use_render_params)
503 {
504   ParticleSystemModifierData *psmd;
505 
506   if (psys->flag & PSYS_DISABLED || psys->flag & PSYS_DELETE || !psys->part) {
507     return 0;
508   }
509 
510   psmd = psys_get_modifier(ob, psys);
511 
512   if (!psmd) {
513     return 0;
514   }
515 
516   if (use_render_params) {
517     if (!(psmd->modifier.mode & eModifierMode_Render)) {
518       return 0;
519     }
520   }
521   else if (!(psmd->modifier.mode & eModifierMode_Realtime)) {
522     return 0;
523   }
524 
525   return 1;
526 }
527 
psys_check_edited(ParticleSystem * psys)528 bool psys_check_edited(ParticleSystem *psys)
529 {
530   if (psys->part && psys->part->type == PART_HAIR) {
531     return (psys->flag & PSYS_EDITED || (psys->edit && psys->edit->edited));
532   }
533 
534   return (psys->pointcache->edit && psys->pointcache->edit->edited);
535 }
536 
psys_find_group_weights(ParticleSettings * part)537 void psys_find_group_weights(ParticleSettings *part)
538 {
539   /* Find object pointers based on index. If the collection is linked from
540    * another library linking may not have the object pointers available on
541    * file load, so we have to retrieve them later. See T49273. */
542   ListBase instance_collection_objects = {NULL, NULL};
543 
544   if (part->instance_collection) {
545     instance_collection_objects = BKE_collection_object_cache_get(part->instance_collection);
546   }
547 
548   LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) {
549     if (dw->ob == NULL) {
550       Base *base = BLI_findlink(&instance_collection_objects, dw->index);
551       if (base != NULL) {
552         dw->ob = base->object;
553       }
554     }
555   }
556 }
557 
psys_check_group_weights(ParticleSettings * part)558 void psys_check_group_weights(ParticleSettings *part)
559 {
560   ParticleDupliWeight *dw, *tdw;
561 
562   if (part->ren_as != PART_DRAW_GR || !part->instance_collection) {
563     BLI_freelistN(&part->instance_weights);
564     return;
565   }
566 
567   /* Find object pointers. */
568   psys_find_group_weights(part);
569 
570   /* Remove NULL objects, that were removed from the collection. */
571   dw = part->instance_weights.first;
572   while (dw) {
573     if (dw->ob == NULL ||
574         !BKE_collection_has_object_recursive(part->instance_collection, dw->ob)) {
575       tdw = dw->next;
576       BLI_freelinkN(&part->instance_weights, dw);
577       dw = tdw;
578     }
579     else {
580       dw = dw->next;
581     }
582   }
583 
584   /* Add new objects in the collection. */
585   int index = 0;
586   FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (part->instance_collection, object) {
587     dw = part->instance_weights.first;
588     while (dw && dw->ob != object) {
589       dw = dw->next;
590     }
591 
592     if (!dw) {
593       dw = MEM_callocN(sizeof(ParticleDupliWeight), "ParticleDupliWeight");
594       dw->ob = object;
595       dw->count = 1;
596       BLI_addtail(&part->instance_weights, dw);
597     }
598 
599     dw->index = index++;
600   }
601   FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
602 
603   /* Ensure there is an element marked as current. */
604   int current = 0;
605   for (dw = part->instance_weights.first; dw; dw = dw->next) {
606     if (dw->flag & PART_DUPLIW_CURRENT) {
607       current = 1;
608       break;
609     }
610   }
611 
612   if (!current) {
613     dw = part->instance_weights.first;
614     if (dw) {
615       dw->flag |= PART_DUPLIW_CURRENT;
616     }
617   }
618 }
619 
psys_uses_gravity(ParticleSimulationData * sim)620 int psys_uses_gravity(ParticleSimulationData *sim)
621 {
622   return sim->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY && sim->psys->part &&
623          sim->psys->part->effector_weights->global_gravity != 0.0f;
624 }
625 /************************************************/
626 /*          Freeing stuff                       */
627 /************************************************/
fluid_free_settings(SPHFluidSettings * fluid)628 static void fluid_free_settings(SPHFluidSettings *fluid)
629 {
630   if (fluid) {
631     MEM_freeN(fluid);
632   }
633 }
634 
free_hair(Object * object,ParticleSystem * psys,int dynamics)635 void free_hair(Object *object, ParticleSystem *psys, int dynamics)
636 {
637   PARTICLE_P;
638 
639   LOOP_PARTICLES
640   {
641     if (pa->hair) {
642       MEM_freeN(pa->hair);
643     }
644     pa->hair = NULL;
645     pa->totkey = 0;
646   }
647 
648   psys->flag &= ~PSYS_HAIR_DONE;
649 
650   if (psys->clmd) {
651     if (dynamics) {
652       BKE_modifier_free((ModifierData *)psys->clmd);
653       psys->clmd = NULL;
654       PTCacheID pid;
655       BKE_ptcache_id_from_particles(&pid, object, psys);
656       BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
657     }
658     else {
659       cloth_free_modifier(psys->clmd);
660     }
661   }
662 
663   if (psys->hair_in_mesh) {
664     BKE_id_free(NULL, psys->hair_in_mesh);
665   }
666   psys->hair_in_mesh = NULL;
667 
668   if (psys->hair_out_mesh) {
669     BKE_id_free(NULL, psys->hair_out_mesh);
670   }
671   psys->hair_out_mesh = NULL;
672 }
free_keyed_keys(ParticleSystem * psys)673 void free_keyed_keys(ParticleSystem *psys)
674 {
675   PARTICLE_P;
676 
677   if (psys->part->type == PART_HAIR) {
678     return;
679   }
680 
681   if (psys->particles && psys->particles->keys) {
682     MEM_freeN(psys->particles->keys);
683 
684     LOOP_PARTICLES
685     {
686       if (pa->keys) {
687         pa->keys = NULL;
688         pa->totkey = 0;
689       }
690     }
691   }
692 }
free_child_path_cache(ParticleSystem * psys)693 static void free_child_path_cache(ParticleSystem *psys)
694 {
695   psys_free_path_cache_buffers(psys->childcache, &psys->childcachebufs);
696   psys->childcache = NULL;
697   psys->totchildcache = 0;
698 }
psys_free_path_cache(ParticleSystem * psys,PTCacheEdit * edit)699 void psys_free_path_cache(ParticleSystem *psys, PTCacheEdit *edit)
700 {
701   if (edit) {
702     psys_free_path_cache_buffers(edit->pathcache, &edit->pathcachebufs);
703     edit->pathcache = NULL;
704     edit->totcached = 0;
705   }
706   if (psys) {
707     psys_free_path_cache_buffers(psys->pathcache, &psys->pathcachebufs);
708     psys->pathcache = NULL;
709     psys->totcached = 0;
710 
711     free_child_path_cache(psys);
712   }
713 }
psys_free_children(ParticleSystem * psys)714 void psys_free_children(ParticleSystem *psys)
715 {
716   if (psys->child) {
717     MEM_freeN(psys->child);
718     psys->child = NULL;
719     psys->totchild = 0;
720   }
721 
722   free_child_path_cache(psys);
723 }
psys_free_particles(ParticleSystem * psys)724 void psys_free_particles(ParticleSystem *psys)
725 {
726   PARTICLE_P;
727 
728   if (psys->particles) {
729     /* Even though psys->part should never be NULL,
730      * this can happen as an exception during deletion.
731      * See ID_REMAP_SKIP/FORCE/FLAG_NEVER_NULL_USAGE in BKE_library_remap. */
732     if (psys->part && psys->part->type == PART_HAIR) {
733       LOOP_PARTICLES
734       {
735         if (pa->hair) {
736           MEM_freeN(pa->hair);
737         }
738       }
739     }
740 
741     if (psys->particles->keys) {
742       MEM_freeN(psys->particles->keys);
743     }
744 
745     if (psys->particles->boid) {
746       MEM_freeN(psys->particles->boid);
747     }
748 
749     MEM_freeN(psys->particles);
750     psys->particles = NULL;
751     psys->totpart = 0;
752   }
753 }
psys_free_pdd(ParticleSystem * psys)754 void psys_free_pdd(ParticleSystem *psys)
755 {
756   if (psys->pdd) {
757     if (psys->pdd->cdata) {
758       MEM_freeN(psys->pdd->cdata);
759     }
760     psys->pdd->cdata = NULL;
761 
762     if (psys->pdd->vdata) {
763       MEM_freeN(psys->pdd->vdata);
764     }
765     psys->pdd->vdata = NULL;
766 
767     if (psys->pdd->ndata) {
768       MEM_freeN(psys->pdd->ndata);
769     }
770     psys->pdd->ndata = NULL;
771 
772     if (psys->pdd->vedata) {
773       MEM_freeN(psys->pdd->vedata);
774     }
775     psys->pdd->vedata = NULL;
776 
777     psys->pdd->totpoint = 0;
778     psys->pdd->totpart = 0;
779     psys->pdd->partsize = 0;
780   }
781 }
782 /* free everything */
psys_free(Object * ob,ParticleSystem * psys)783 void psys_free(Object *ob, ParticleSystem *psys)
784 {
785   if (psys) {
786     int nr = 0;
787     ParticleSystem *tpsys;
788 
789     psys_free_path_cache(psys, NULL);
790 
791     /* NOTE: We pass dynamics=0 to free_hair() to prevent it from doing an
792      * unneeded clear of the cache. But for historical reason that code path
793      * was only clearing cloth part of modifier data.
794      *
795      * Part of the story there is that particle evaluation is trying to not
796      * re-allocate thew ModifierData itself, and limits all allocations to
797      * the cloth part of it.
798      *
799      * Why evaluation is relying on hair_free() and in some specific code
800      * paths there is beyond me.
801      */
802     free_hair(ob, psys, 0);
803     if (psys->clmd != NULL) {
804       BKE_modifier_free((ModifierData *)psys->clmd);
805     }
806 
807     psys_free_particles(psys);
808 
809     if (psys->edit && psys->free_edit) {
810       psys->free_edit(psys->edit);
811     }
812 
813     if (psys->child) {
814       MEM_freeN(psys->child);
815       psys->child = NULL;
816       psys->totchild = 0;
817     }
818 
819     /* check if we are last non-visible particle system */
820     for (tpsys = ob->particlesystem.first; tpsys; tpsys = tpsys->next) {
821       if (tpsys->part) {
822         if (ELEM(tpsys->part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
823           nr++;
824           break;
825         }
826       }
827     }
828     /* clear do-not-draw-flag */
829     if (!nr) {
830       ob->transflag &= ~OB_DUPLIPARTS;
831     }
832 
833     psys->part = NULL;
834 
835     if ((psys->flag & PSYS_SHARED_CACHES) == 0) {
836       BKE_ptcache_free_list(&psys->ptcaches);
837     }
838     psys->pointcache = NULL;
839 
840     BLI_freelistN(&psys->targets);
841 
842     BLI_bvhtree_free(psys->bvhtree);
843     BLI_kdtree_3d_free(psys->tree);
844 
845     if (psys->fluid_springs) {
846       MEM_freeN(psys->fluid_springs);
847     }
848 
849     BKE_effectors_free(psys->effectors);
850 
851     if (psys->pdd) {
852       psys_free_pdd(psys);
853       MEM_freeN(psys->pdd);
854     }
855 
856     BKE_particle_batch_cache_free(psys);
857 
858     MEM_freeN(psys);
859   }
860 }
861 
psys_copy_particles(ParticleSystem * psys_dst,ParticleSystem * psys_src)862 void psys_copy_particles(ParticleSystem *psys_dst, ParticleSystem *psys_src)
863 {
864   /* Free existing particles. */
865   if (psys_dst->particles != psys_src->particles) {
866     psys_free_particles(psys_dst);
867   }
868   if (psys_dst->child != psys_src->child) {
869     psys_free_children(psys_dst);
870   }
871   /* Restore counters. */
872   psys_dst->totpart = psys_src->totpart;
873   psys_dst->totchild = psys_src->totchild;
874   /* Copy particles and children. */
875   psys_dst->particles = MEM_dupallocN(psys_src->particles);
876   psys_dst->child = MEM_dupallocN(psys_src->child);
877   if (psys_dst->part->type == PART_HAIR) {
878     ParticleData *pa;
879     int p;
880     for (p = 0, pa = psys_dst->particles; p < psys_dst->totpart; p++, pa++) {
881       pa->hair = MEM_dupallocN(pa->hair);
882     }
883   }
884   if (psys_dst->particles && (psys_dst->particles->keys || psys_dst->particles->boid)) {
885     ParticleKey *key = psys_dst->particles->keys;
886     BoidParticle *boid = psys_dst->particles->boid;
887     ParticleData *pa;
888     int p;
889     if (key != NULL) {
890       key = MEM_dupallocN(key);
891     }
892     if (boid != NULL) {
893       boid = MEM_dupallocN(boid);
894     }
895     for (p = 0, pa = psys_dst->particles; p < psys_dst->totpart; p++, pa++) {
896       if (boid != NULL) {
897         pa->boid = boid++;
898       }
899       if (key != NULL) {
900         pa->keys = key;
901         key += pa->totkey;
902       }
903     }
904   }
905 }
906 
907 /************************************************/
908 /*          Interpolation                       */
909 /************************************************/
interpolate_particle_value(float v1,float v2,float v3,float v4,const float w[4],int four)910 static float interpolate_particle_value(
911     float v1, float v2, float v3, float v4, const float w[4], int four)
912 {
913   float value;
914 
915   value = w[0] * v1 + w[1] * v2 + w[2] * v3;
916   if (four) {
917     value += w[3] * v4;
918   }
919 
920   CLAMP(value, 0.f, 1.f);
921 
922   return value;
923 }
924 
psys_interpolate_particle(short type,ParticleKey keys[4],float dt,ParticleKey * result,bool velocity)925 void psys_interpolate_particle(
926     short type, ParticleKey keys[4], float dt, ParticleKey *result, bool velocity)
927 {
928   float t[4];
929 
930   if (type < 0) {
931     interp_cubic_v3(result->co, result->vel, keys[1].co, keys[1].vel, keys[2].co, keys[2].vel, dt);
932   }
933   else {
934     key_curve_position_weights(dt, t, type);
935 
936     interp_v3_v3v3v3v3(result->co, keys[0].co, keys[1].co, keys[2].co, keys[3].co, t);
937 
938     if (velocity) {
939       float temp[3];
940 
941       if (dt > 0.999f) {
942         key_curve_position_weights(dt - 0.001f, t, type);
943         interp_v3_v3v3v3v3(temp, keys[0].co, keys[1].co, keys[2].co, keys[3].co, t);
944         sub_v3_v3v3(result->vel, result->co, temp);
945       }
946       else {
947         key_curve_position_weights(dt + 0.001f, t, type);
948         interp_v3_v3v3v3v3(temp, keys[0].co, keys[1].co, keys[2].co, keys[3].co, t);
949         sub_v3_v3v3(result->vel, temp, result->co);
950       }
951     }
952   }
953 }
954 
955 typedef struct ParticleInterpolationData {
956   HairKey *hkey[2];
957 
958   Mesh *mesh;
959   MVert *mvert[2];
960 
961   int keyed;
962   ParticleKey *kkey[2];
963 
964   PointCache *cache;
965   PTCacheMem *pm;
966 
967   PTCacheEditPoint *epoint;
968   PTCacheEditKey *ekey[2];
969 
970   float birthtime, dietime;
971   int bspline;
972 } ParticleInterpolationData;
973 /**
974  * Assumes pointcache->mem_cache exists, so for disk cached particles
975  * call #psys_make_temp_pointcache() before use.
976  * It uses #ParticleInterpolationData.pm to store the current memory cache frame
977  * so it's thread safe.
978  */
get_pointcache_keys_for_time(Object * UNUSED (ob),PointCache * cache,PTCacheMem ** cur,int index,float t,ParticleKey * key1,ParticleKey * key2)979 static void get_pointcache_keys_for_time(Object *UNUSED(ob),
980                                          PointCache *cache,
981                                          PTCacheMem **cur,
982                                          int index,
983                                          float t,
984                                          ParticleKey *key1,
985                                          ParticleKey *key2)
986 {
987   static PTCacheMem *pm = NULL;
988   int index1, index2;
989 
990   if (index < 0) { /* initialize */
991     *cur = cache->mem_cache.first;
992 
993     if (*cur) {
994       *cur = (*cur)->next;
995     }
996   }
997   else {
998     if (*cur) {
999       while (*cur && (*cur)->next && (float)(*cur)->frame < t) {
1000         *cur = (*cur)->next;
1001       }
1002 
1003       pm = *cur;
1004 
1005       index2 = BKE_ptcache_mem_index_find(pm, index);
1006       index1 = BKE_ptcache_mem_index_find(pm->prev, index);
1007       if (index2 < 0) {
1008         return;
1009       }
1010 
1011       BKE_ptcache_make_particle_key(key2, index2, pm->data, (float)pm->frame);
1012       if (index1 < 0) {
1013         copy_particle_key(key1, key2, 1);
1014       }
1015       else {
1016         BKE_ptcache_make_particle_key(key1, index1, pm->prev->data, (float)pm->prev->frame);
1017       }
1018     }
1019     else if (cache->mem_cache.first) {
1020       pm = cache->mem_cache.first;
1021       index2 = BKE_ptcache_mem_index_find(pm, index);
1022       if (index2 < 0) {
1023         return;
1024       }
1025       BKE_ptcache_make_particle_key(key2, index2, pm->data, (float)pm->frame);
1026       copy_particle_key(key1, key2, 1);
1027     }
1028   }
1029 }
get_pointcache_times_for_particle(PointCache * cache,int index,float * start,float * end)1030 static int get_pointcache_times_for_particle(PointCache *cache,
1031                                              int index,
1032                                              float *start,
1033                                              float *end)
1034 {
1035   PTCacheMem *pm;
1036   int ret = 0;
1037 
1038   for (pm = cache->mem_cache.first; pm; pm = pm->next) {
1039     if (BKE_ptcache_mem_index_find(pm, index) >= 0) {
1040       *start = pm->frame;
1041       ret++;
1042       break;
1043     }
1044   }
1045 
1046   for (pm = cache->mem_cache.last; pm; pm = pm->prev) {
1047     if (BKE_ptcache_mem_index_find(pm, index) >= 0) {
1048       *end = pm->frame;
1049       ret++;
1050       break;
1051     }
1052   }
1053 
1054   return ret == 2;
1055 }
1056 
psys_get_dietime_from_cache(PointCache * cache,int index)1057 float psys_get_dietime_from_cache(PointCache *cache, int index)
1058 {
1059   PTCacheMem *pm;
1060   int dietime = 10000000; /* some max value so that we can default to pa->time+lifetime */
1061 
1062   for (pm = cache->mem_cache.last; pm; pm = pm->prev) {
1063     if (BKE_ptcache_mem_index_find(pm, index) >= 0) {
1064       return (float)pm->frame;
1065     }
1066   }
1067 
1068   return (float)dietime;
1069 }
1070 
init_particle_interpolation(Object * ob,ParticleSystem * psys,ParticleData * pa,ParticleInterpolationData * pind)1071 static void init_particle_interpolation(Object *ob,
1072                                         ParticleSystem *psys,
1073                                         ParticleData *pa,
1074                                         ParticleInterpolationData *pind)
1075 {
1076 
1077   if (pind->epoint) {
1078     PTCacheEditPoint *point = pind->epoint;
1079 
1080     pind->ekey[0] = point->keys;
1081     pind->ekey[1] = point->totkey > 1 ? point->keys + 1 : NULL;
1082 
1083     pind->birthtime = *(point->keys->time);
1084     pind->dietime = *((point->keys + point->totkey - 1)->time);
1085   }
1086   else if (pind->keyed) {
1087     ParticleKey *key = pa->keys;
1088     pind->kkey[0] = key;
1089     pind->kkey[1] = pa->totkey > 1 ? key + 1 : NULL;
1090 
1091     pind->birthtime = key->time;
1092     pind->dietime = (key + pa->totkey - 1)->time;
1093   }
1094   else if (pind->cache) {
1095     float start = 0.0f, end = 0.0f;
1096     get_pointcache_keys_for_time(ob, pind->cache, &pind->pm, -1, 0.0f, NULL, NULL);
1097     pind->birthtime = pa ? pa->time : pind->cache->startframe;
1098     pind->dietime = pa ? pa->dietime : pind->cache->endframe;
1099 
1100     if (get_pointcache_times_for_particle(pind->cache, pa - psys->particles, &start, &end)) {
1101       pind->birthtime = MAX2(pind->birthtime, start);
1102       pind->dietime = MIN2(pind->dietime, end);
1103     }
1104   }
1105   else {
1106     HairKey *key = pa->hair;
1107     pind->hkey[0] = key;
1108     pind->hkey[1] = key + 1;
1109 
1110     pind->birthtime = key->time;
1111     pind->dietime = (key + pa->totkey - 1)->time;
1112 
1113     if (pind->mesh) {
1114       pind->mvert[0] = &pind->mesh->mvert[pa->hair_index];
1115       pind->mvert[1] = pind->mvert[0] + 1;
1116     }
1117   }
1118 }
edit_to_particle(ParticleKey * key,PTCacheEditKey * ekey)1119 static void edit_to_particle(ParticleKey *key, PTCacheEditKey *ekey)
1120 {
1121   copy_v3_v3(key->co, ekey->co);
1122   if (ekey->vel) {
1123     copy_v3_v3(key->vel, ekey->vel);
1124   }
1125   key->time = *(ekey->time);
1126 }
hair_to_particle(ParticleKey * key,HairKey * hkey)1127 static void hair_to_particle(ParticleKey *key, HairKey *hkey)
1128 {
1129   copy_v3_v3(key->co, hkey->co);
1130   key->time = hkey->time;
1131 }
1132 
mvert_to_particle(ParticleKey * key,MVert * mvert,HairKey * hkey)1133 static void mvert_to_particle(ParticleKey *key, MVert *mvert, HairKey *hkey)
1134 {
1135   copy_v3_v3(key->co, mvert->co);
1136   key->time = hkey->time;
1137 }
1138 
do_particle_interpolation(ParticleSystem * psys,int p,ParticleData * pa,float t,ParticleInterpolationData * pind,ParticleKey * result)1139 static void do_particle_interpolation(ParticleSystem *psys,
1140                                       int p,
1141                                       ParticleData *pa,
1142                                       float t,
1143                                       ParticleInterpolationData *pind,
1144                                       ParticleKey *result)
1145 {
1146   PTCacheEditPoint *point = pind->epoint;
1147   ParticleKey keys[4];
1148   int point_vel = (point && point->keys->vel);
1149   float real_t, dfra, keytime, invdt = 1.f;
1150 
1151   /* billboards wont fill in all of these, so start cleared */
1152   memset(keys, 0, sizeof(keys));
1153 
1154   /* interpret timing and find keys */
1155   if (point) {
1156     if (result->time < 0.0f) {
1157       real_t = -result->time;
1158     }
1159     else {
1160       real_t = *(pind->ekey[0]->time) +
1161                t * (*(pind->ekey[0][point->totkey - 1].time) - *(pind->ekey[0]->time));
1162     }
1163 
1164     while (*(pind->ekey[1]->time) < real_t) {
1165       pind->ekey[1]++;
1166     }
1167 
1168     pind->ekey[0] = pind->ekey[1] - 1;
1169   }
1170   else if (pind->keyed) {
1171     /* we have only one key, so let's use that */
1172     if (pind->kkey[1] == NULL) {
1173       copy_particle_key(result, pind->kkey[0], 1);
1174       return;
1175     }
1176 
1177     if (result->time < 0.0f) {
1178       real_t = -result->time;
1179     }
1180     else {
1181       real_t = pind->kkey[0]->time +
1182                t * (pind->kkey[0][pa->totkey - 1].time - pind->kkey[0]->time);
1183     }
1184 
1185     if (psys->part->phystype == PART_PHYS_KEYED && psys->flag & PSYS_KEYED_TIMING) {
1186       ParticleTarget *pt = psys->targets.first;
1187 
1188       pt = pt->next;
1189 
1190       while (pt && pa->time + pt->time < real_t) {
1191         pt = pt->next;
1192       }
1193 
1194       if (pt) {
1195         pt = pt->prev;
1196 
1197         if (pa->time + pt->time + pt->duration > real_t) {
1198           real_t = pa->time + pt->time;
1199         }
1200       }
1201       else {
1202         real_t = pa->time + ((ParticleTarget *)psys->targets.last)->time;
1203       }
1204     }
1205 
1206     CLAMP(real_t, pa->time, pa->dietime);
1207 
1208     while (pind->kkey[1]->time < real_t) {
1209       pind->kkey[1]++;
1210     }
1211 
1212     pind->kkey[0] = pind->kkey[1] - 1;
1213   }
1214   else if (pind->cache) {
1215     if (result->time < 0.0f) { /* flag for time in frames */
1216       real_t = -result->time;
1217     }
1218     else {
1219       real_t = pa->time + t * (pa->dietime - pa->time);
1220     }
1221   }
1222   else {
1223     if (result->time < 0.0f) {
1224       real_t = -result->time;
1225     }
1226     else {
1227       real_t = pind->hkey[0]->time +
1228                t * (pind->hkey[0][pa->totkey - 1].time - pind->hkey[0]->time);
1229     }
1230 
1231     while (pind->hkey[1]->time < real_t) {
1232       pind->hkey[1]++;
1233       pind->mvert[1]++;
1234     }
1235 
1236     pind->hkey[0] = pind->hkey[1] - 1;
1237   }
1238 
1239   /* set actual interpolation keys */
1240   if (point) {
1241     edit_to_particle(keys + 1, pind->ekey[0]);
1242     edit_to_particle(keys + 2, pind->ekey[1]);
1243   }
1244   else if (pind->mesh) {
1245     pind->mvert[0] = pind->mvert[1] - 1;
1246     mvert_to_particle(keys + 1, pind->mvert[0], pind->hkey[0]);
1247     mvert_to_particle(keys + 2, pind->mvert[1], pind->hkey[1]);
1248   }
1249   else if (pind->keyed) {
1250     memcpy(keys + 1, pind->kkey[0], sizeof(ParticleKey));
1251     memcpy(keys + 2, pind->kkey[1], sizeof(ParticleKey));
1252   }
1253   else if (pind->cache) {
1254     get_pointcache_keys_for_time(NULL, pind->cache, &pind->pm, p, real_t, keys + 1, keys + 2);
1255   }
1256   else {
1257     hair_to_particle(keys + 1, pind->hkey[0]);
1258     hair_to_particle(keys + 2, pind->hkey[1]);
1259   }
1260 
1261   /* set secondary interpolation keys for hair */
1262   if (!pind->keyed && !pind->cache && !point_vel) {
1263     if (point) {
1264       if (pind->ekey[0] != point->keys) {
1265         edit_to_particle(keys, pind->ekey[0] - 1);
1266       }
1267       else {
1268         edit_to_particle(keys, pind->ekey[0]);
1269       }
1270     }
1271     else if (pind->mesh) {
1272       if (pind->hkey[0] != pa->hair) {
1273         mvert_to_particle(keys, pind->mvert[0] - 1, pind->hkey[0] - 1);
1274       }
1275       else {
1276         mvert_to_particle(keys, pind->mvert[0], pind->hkey[0]);
1277       }
1278     }
1279     else {
1280       if (pind->hkey[0] != pa->hair) {
1281         hair_to_particle(keys, pind->hkey[0] - 1);
1282       }
1283       else {
1284         hair_to_particle(keys, pind->hkey[0]);
1285       }
1286     }
1287 
1288     if (point) {
1289       if (pind->ekey[1] != point->keys + point->totkey - 1) {
1290         edit_to_particle(keys + 3, pind->ekey[1] + 1);
1291       }
1292       else {
1293         edit_to_particle(keys + 3, pind->ekey[1]);
1294       }
1295     }
1296     else if (pind->mesh) {
1297       if (pind->hkey[1] != pa->hair + pa->totkey - 1) {
1298         mvert_to_particle(keys + 3, pind->mvert[1] + 1, pind->hkey[1] + 1);
1299       }
1300       else {
1301         mvert_to_particle(keys + 3, pind->mvert[1], pind->hkey[1]);
1302       }
1303     }
1304     else {
1305       if (pind->hkey[1] != pa->hair + pa->totkey - 1) {
1306         hair_to_particle(keys + 3, pind->hkey[1] + 1);
1307       }
1308       else {
1309         hair_to_particle(keys + 3, pind->hkey[1]);
1310       }
1311     }
1312   }
1313 
1314   dfra = keys[2].time - keys[1].time;
1315   keytime = (real_t - keys[1].time) / dfra;
1316 
1317   /* Convert velocity to time-step size. */
1318   if (pind->keyed || pind->cache || point_vel) {
1319     invdt = dfra * 0.04f * (psys ? psys->part->timetweak : 1.f);
1320     mul_v3_fl(keys[1].vel, invdt);
1321     mul_v3_fl(keys[2].vel, invdt);
1322     interp_qt_qtqt(result->rot, keys[1].rot, keys[2].rot, keytime);
1323   }
1324 
1325   /* Now we should have in chronological order k1<=k2<=t<=k3<=k4 with key-time between
1326    * [0, 1]->[k2, k3] (k1 & k4 used for cardinal & b-spline interpolation). */
1327   psys_interpolate_particle((pind->keyed || pind->cache || point_vel) ?
1328                                 -1 /* signal for cubic interpolation */
1329                                 :
1330                                 (pind->bspline ? KEY_BSPLINE : KEY_CARDINAL),
1331                             keys,
1332                             keytime,
1333                             result,
1334                             1);
1335 
1336   /* the velocity needs to be converted back from cubic interpolation */
1337   if (pind->keyed || pind->cache || point_vel) {
1338     mul_v3_fl(result->vel, 1.f / invdt);
1339   }
1340 }
1341 
interpolate_pathcache(ParticleCacheKey * first,float t,ParticleCacheKey * result)1342 static void interpolate_pathcache(ParticleCacheKey *first, float t, ParticleCacheKey *result)
1343 {
1344   int i = 0;
1345   ParticleCacheKey *cur = first;
1346 
1347   /* scale the requested time to fit the entire path even if the path is cut early */
1348   t *= (first + first->segments)->time;
1349 
1350   while (i < first->segments && cur->time < t) {
1351     cur++;
1352   }
1353 
1354   if (cur->time == t) {
1355     *result = *cur;
1356   }
1357   else {
1358     float dt = (t - (cur - 1)->time) / (cur->time - (cur - 1)->time);
1359     interp_v3_v3v3(result->co, (cur - 1)->co, cur->co, dt);
1360     interp_v3_v3v3(result->vel, (cur - 1)->vel, cur->vel, dt);
1361     interp_qt_qtqt(result->rot, (cur - 1)->rot, cur->rot, dt);
1362     result->time = t;
1363   }
1364 
1365   /* first is actual base rotation, others are incremental from first */
1366   if (cur == first || cur - 1 == first) {
1367     copy_qt_qt(result->rot, first->rot);
1368   }
1369   else {
1370     mul_qt_qtqt(result->rot, first->rot, result->rot);
1371   }
1372 }
1373 
1374 /************************************************/
1375 /*          Particles on a dm                   */
1376 /************************************************/
1377 /* interpolate a location on a face based on face coordinates */
psys_interpolate_face(MVert * mvert,MFace * mface,MTFace * tface,float (* orcodata)[3],float w[4],float vec[3],float nor[3],float utan[3],float vtan[3],float orco[3])1378 void psys_interpolate_face(MVert *mvert,
1379                            MFace *mface,
1380                            MTFace *tface,
1381                            float (*orcodata)[3],
1382                            float w[4],
1383                            float vec[3],
1384                            float nor[3],
1385                            float utan[3],
1386                            float vtan[3],
1387                            float orco[3])
1388 {
1389   float *v1 = 0, *v2 = 0, *v3 = 0, *v4 = 0;
1390   float e1[3], e2[3], s1, s2, t1, t2;
1391   float *uv1, *uv2, *uv3, *uv4;
1392   float n1[3], n2[3], n3[3], n4[3];
1393   float tuv[4][2];
1394   float *o1, *o2, *o3, *o4;
1395 
1396   v1 = mvert[mface->v1].co;
1397   v2 = mvert[mface->v2].co;
1398   v3 = mvert[mface->v3].co;
1399 
1400   normal_short_to_float_v3(n1, mvert[mface->v1].no);
1401   normal_short_to_float_v3(n2, mvert[mface->v2].no);
1402   normal_short_to_float_v3(n3, mvert[mface->v3].no);
1403 
1404   if (mface->v4) {
1405     v4 = mvert[mface->v4].co;
1406     normal_short_to_float_v3(n4, mvert[mface->v4].no);
1407 
1408     interp_v3_v3v3v3v3(vec, v1, v2, v3, v4, w);
1409 
1410     if (nor) {
1411       if (mface->flag & ME_SMOOTH) {
1412         interp_v3_v3v3v3v3(nor, n1, n2, n3, n4, w);
1413       }
1414       else {
1415         normal_quad_v3(nor, v1, v2, v3, v4);
1416       }
1417     }
1418   }
1419   else {
1420     interp_v3_v3v3v3(vec, v1, v2, v3, w);
1421 
1422     if (nor) {
1423       if (mface->flag & ME_SMOOTH) {
1424         interp_v3_v3v3v3(nor, n1, n2, n3, w);
1425       }
1426       else {
1427         normal_tri_v3(nor, v1, v2, v3);
1428       }
1429     }
1430   }
1431 
1432   /* calculate tangent vectors */
1433   if (utan && vtan) {
1434     if (tface) {
1435       uv1 = tface->uv[0];
1436       uv2 = tface->uv[1];
1437       uv3 = tface->uv[2];
1438       uv4 = tface->uv[3];
1439     }
1440     else {
1441       uv1 = tuv[0];
1442       uv2 = tuv[1];
1443       uv3 = tuv[2];
1444       uv4 = tuv[3];
1445       map_to_sphere(uv1, uv1 + 1, v1[0], v1[1], v1[2]);
1446       map_to_sphere(uv2, uv2 + 1, v2[0], v2[1], v2[2]);
1447       map_to_sphere(uv3, uv3 + 1, v3[0], v3[1], v3[2]);
1448       if (v4) {
1449         map_to_sphere(uv4, uv4 + 1, v4[0], v4[1], v4[2]);
1450       }
1451     }
1452 
1453     if (v4) {
1454       s1 = uv3[0] - uv1[0];
1455       s2 = uv4[0] - uv1[0];
1456 
1457       t1 = uv3[1] - uv1[1];
1458       t2 = uv4[1] - uv1[1];
1459 
1460       sub_v3_v3v3(e1, v3, v1);
1461       sub_v3_v3v3(e2, v4, v1);
1462     }
1463     else {
1464       s1 = uv2[0] - uv1[0];
1465       s2 = uv3[0] - uv1[0];
1466 
1467       t1 = uv2[1] - uv1[1];
1468       t2 = uv3[1] - uv1[1];
1469 
1470       sub_v3_v3v3(e1, v2, v1);
1471       sub_v3_v3v3(e2, v3, v1);
1472     }
1473 
1474     vtan[0] = (s1 * e2[0] - s2 * e1[0]);
1475     vtan[1] = (s1 * e2[1] - s2 * e1[1]);
1476     vtan[2] = (s1 * e2[2] - s2 * e1[2]);
1477 
1478     utan[0] = (t1 * e2[0] - t2 * e1[0]);
1479     utan[1] = (t1 * e2[1] - t2 * e1[1]);
1480     utan[2] = (t1 * e2[2] - t2 * e1[2]);
1481   }
1482 
1483   if (orco) {
1484     if (orcodata) {
1485       o1 = orcodata[mface->v1];
1486       o2 = orcodata[mface->v2];
1487       o3 = orcodata[mface->v3];
1488 
1489       if (mface->v4) {
1490         o4 = orcodata[mface->v4];
1491 
1492         interp_v3_v3v3v3v3(orco, o1, o2, o3, o4, w);
1493       }
1494       else {
1495         interp_v3_v3v3v3(orco, o1, o2, o3, w);
1496       }
1497     }
1498     else {
1499       copy_v3_v3(orco, vec);
1500     }
1501   }
1502 }
psys_interpolate_uvs(const MTFace * tface,int quad,const float w[4],float uvco[2])1503 void psys_interpolate_uvs(const MTFace *tface, int quad, const float w[4], float uvco[2])
1504 {
1505   float v10 = tface->uv[0][0];
1506   float v11 = tface->uv[0][1];
1507   float v20 = tface->uv[1][0];
1508   float v21 = tface->uv[1][1];
1509   float v30 = tface->uv[2][0];
1510   float v31 = tface->uv[2][1];
1511   float v40, v41;
1512 
1513   if (quad) {
1514     v40 = tface->uv[3][0];
1515     v41 = tface->uv[3][1];
1516 
1517     uvco[0] = w[0] * v10 + w[1] * v20 + w[2] * v30 + w[3] * v40;
1518     uvco[1] = w[0] * v11 + w[1] * v21 + w[2] * v31 + w[3] * v41;
1519   }
1520   else {
1521     uvco[0] = w[0] * v10 + w[1] * v20 + w[2] * v30;
1522     uvco[1] = w[0] * v11 + w[1] * v21 + w[2] * v31;
1523   }
1524 }
1525 
psys_interpolate_mcol(const MCol * mcol,int quad,const float w[4],MCol * mc)1526 void psys_interpolate_mcol(const MCol *mcol, int quad, const float w[4], MCol *mc)
1527 {
1528   const char *cp1, *cp2, *cp3, *cp4;
1529   char *cp;
1530 
1531   cp = (char *)mc;
1532   cp1 = (const char *)&mcol[0];
1533   cp2 = (const char *)&mcol[1];
1534   cp3 = (const char *)&mcol[2];
1535 
1536   if (quad) {
1537     cp4 = (char *)&mcol[3];
1538 
1539     cp[0] = (int)(w[0] * cp1[0] + w[1] * cp2[0] + w[2] * cp3[0] + w[3] * cp4[0]);
1540     cp[1] = (int)(w[0] * cp1[1] + w[1] * cp2[1] + w[2] * cp3[1] + w[3] * cp4[1]);
1541     cp[2] = (int)(w[0] * cp1[2] + w[1] * cp2[2] + w[2] * cp3[2] + w[3] * cp4[2]);
1542     cp[3] = (int)(w[0] * cp1[3] + w[1] * cp2[3] + w[2] * cp3[3] + w[3] * cp4[3]);
1543   }
1544   else {
1545     cp[0] = (int)(w[0] * cp1[0] + w[1] * cp2[0] + w[2] * cp3[0]);
1546     cp[1] = (int)(w[0] * cp1[1] + w[1] * cp2[1] + w[2] * cp3[1]);
1547     cp[2] = (int)(w[0] * cp1[2] + w[1] * cp2[2] + w[2] * cp3[2]);
1548     cp[3] = (int)(w[0] * cp1[3] + w[1] * cp2[3] + w[2] * cp3[3]);
1549   }
1550 }
1551 
psys_interpolate_value_from_verts(Mesh * mesh,short from,int index,const float fw[4],const float * values)1552 static float psys_interpolate_value_from_verts(
1553     Mesh *mesh, short from, int index, const float fw[4], const float *values)
1554 {
1555   if (values == 0 || index == -1) {
1556     return 0.0;
1557   }
1558 
1559   switch (from) {
1560     case PART_FROM_VERT:
1561       return values[index];
1562     case PART_FROM_FACE:
1563     case PART_FROM_VOLUME: {
1564       MFace *mf = &mesh->mface[index];
1565       return interpolate_particle_value(
1566           values[mf->v1], values[mf->v2], values[mf->v3], values[mf->v4], fw, mf->v4);
1567     }
1568   }
1569   return 0.0f;
1570 }
1571 
1572 /* conversion of pa->fw to origspace layer coordinates */
psys_w_to_origspace(const float w[4],float uv[2])1573 static void psys_w_to_origspace(const float w[4], float uv[2])
1574 {
1575   uv[0] = w[1] + w[2];
1576   uv[1] = w[2] + w[3];
1577 }
1578 
1579 /* conversion of pa->fw to weights in face from origspace */
psys_origspace_to_w(OrigSpaceFace * osface,int quad,const float w[4],float neww[4])1580 static void psys_origspace_to_w(OrigSpaceFace *osface, int quad, const float w[4], float neww[4])
1581 {
1582   float v[4][3], co[3];
1583 
1584   v[0][0] = osface->uv[0][0];
1585   v[0][1] = osface->uv[0][1];
1586   v[0][2] = 0.0f;
1587   v[1][0] = osface->uv[1][0];
1588   v[1][1] = osface->uv[1][1];
1589   v[1][2] = 0.0f;
1590   v[2][0] = osface->uv[2][0];
1591   v[2][1] = osface->uv[2][1];
1592   v[2][2] = 0.0f;
1593 
1594   psys_w_to_origspace(w, co);
1595   co[2] = 0.0f;
1596 
1597   if (quad) {
1598     v[3][0] = osface->uv[3][0];
1599     v[3][1] = osface->uv[3][1];
1600     v[3][2] = 0.0f;
1601     interp_weights_poly_v3(neww, v, 4, co);
1602   }
1603   else {
1604     interp_weights_poly_v3(neww, v, 3, co);
1605     neww[3] = 0.0f;
1606   }
1607 }
1608 
1609 /**
1610  * Find the final derived mesh tessface for a particle, from its original tessface index.
1611  * This is slow and can be optimized but only for many lookups.
1612  *
1613  * \param mesh_final: Final mesh, it may not have the same topology as original mesh.
1614  * \param mesh_original: Original mesh, use for accessing #MPoly to #MFace mapping.
1615  * \param findex_orig: The input tessface index.
1616  * \param fw: Face weights (position of the particle inside the \a findex_orig tessface).
1617  * \param poly_nodes: May be NULL, otherwise an array of linked list,
1618  * one for each final \a mesh_final polygon, containing all its tessfaces indices.
1619  * \return The \a mesh_final tessface index.
1620  */
psys_particle_dm_face_lookup(Mesh * mesh_final,Mesh * mesh_original,int findex_orig,const float fw[4],struct LinkNode ** poly_nodes)1621 int psys_particle_dm_face_lookup(Mesh *mesh_final,
1622                                  Mesh *mesh_original,
1623                                  int findex_orig,
1624                                  const float fw[4],
1625                                  struct LinkNode **poly_nodes)
1626 {
1627   MFace *mtessface_final;
1628   OrigSpaceFace *osface_final;
1629   int pindex_orig;
1630   float uv[2], (*faceuv)[2];
1631 
1632   const int *index_mf_to_mpoly_deformed = NULL;
1633   const int *index_mf_to_mpoly = NULL;
1634   const int *index_mp_to_orig = NULL;
1635 
1636   const int totface_final = mesh_final->totface;
1637   const int totface_deformed = mesh_original ? mesh_original->totface : totface_final;
1638 
1639   if (ELEM(0, totface_final, totface_deformed)) {
1640     return DMCACHE_NOTFOUND;
1641   }
1642 
1643   index_mf_to_mpoly = CustomData_get_layer(&mesh_final->fdata, CD_ORIGINDEX);
1644   index_mp_to_orig = CustomData_get_layer(&mesh_final->pdata, CD_ORIGINDEX);
1645   BLI_assert(index_mf_to_mpoly);
1646 
1647   if (mesh_original) {
1648     index_mf_to_mpoly_deformed = CustomData_get_layer(&mesh_original->fdata, CD_ORIGINDEX);
1649   }
1650   else {
1651     BLI_assert(mesh_final->runtime.deformed_only);
1652     index_mf_to_mpoly_deformed = index_mf_to_mpoly;
1653   }
1654   BLI_assert(index_mf_to_mpoly_deformed);
1655 
1656   pindex_orig = index_mf_to_mpoly_deformed[findex_orig];
1657 
1658   if (mesh_original == NULL) {
1659     mesh_original = mesh_final;
1660   }
1661 
1662   index_mf_to_mpoly_deformed = NULL;
1663 
1664   mtessface_final = mesh_final->mface;
1665   osface_final = CustomData_get_layer(&mesh_final->fdata, CD_ORIGSPACE);
1666 
1667   if (osface_final == NULL) {
1668     /* Assume we don't need osface_final data, and we get a direct 1-1 mapping... */
1669     if (findex_orig < totface_final) {
1670       // printf("\tNO CD_ORIGSPACE, assuming not needed\n");
1671       return findex_orig;
1672     }
1673 
1674     printf("\tNO CD_ORIGSPACE, error out of range\n");
1675     return DMCACHE_NOTFOUND;
1676   }
1677   if (findex_orig >= mesh_original->totface) {
1678     return DMCACHE_NOTFOUND; /* index not in the original mesh */
1679   }
1680 
1681   psys_w_to_origspace(fw, uv);
1682 
1683   if (poly_nodes) {
1684     /* we can have a restricted linked list of faces to check, faster! */
1685     LinkNode *tessface_node = poly_nodes[pindex_orig];
1686 
1687     for (; tessface_node; tessface_node = tessface_node->next) {
1688       int findex_dst = POINTER_AS_INT(tessface_node->link);
1689       faceuv = osface_final[findex_dst].uv;
1690 
1691       /* check that this intersects - Its possible this misses :/ -
1692        * could also check its not between */
1693       if (mtessface_final[findex_dst].v4) {
1694         if (isect_point_quad_v2(uv, faceuv[0], faceuv[1], faceuv[2], faceuv[3])) {
1695           return findex_dst;
1696         }
1697       }
1698       else if (isect_point_tri_v2(uv, faceuv[0], faceuv[1], faceuv[2])) {
1699         return findex_dst;
1700       }
1701     }
1702   }
1703   else { /* if we have no node, try every face */
1704     for (int findex_dst = 0; findex_dst < totface_final; findex_dst++) {
1705       /* If current tessface from 'final' DM and orig tessface (given by index)
1706        * map to the same orig poly. */
1707       if (BKE_mesh_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, findex_dst) ==
1708           pindex_orig) {
1709         faceuv = osface_final[findex_dst].uv;
1710 
1711         /* check that this intersects - Its possible this misses :/ -
1712          * could also check its not between */
1713         if (mtessface_final[findex_dst].v4) {
1714           if (isect_point_quad_v2(uv, faceuv[0], faceuv[1], faceuv[2], faceuv[3])) {
1715             return findex_dst;
1716           }
1717         }
1718         else if (isect_point_tri_v2(uv, faceuv[0], faceuv[1], faceuv[2])) {
1719           return findex_dst;
1720         }
1721       }
1722     }
1723   }
1724 
1725   return DMCACHE_NOTFOUND;
1726 }
1727 
psys_map_index_on_dm(Mesh * mesh,int from,int index,int index_dmcache,const float fw[4],float UNUSED (foffset),int * mapindex,float mapfw[4])1728 static int psys_map_index_on_dm(Mesh *mesh,
1729                                 int from,
1730                                 int index,
1731                                 int index_dmcache,
1732                                 const float fw[4],
1733                                 float UNUSED(foffset),
1734                                 int *mapindex,
1735                                 float mapfw[4])
1736 {
1737   if (index < 0) {
1738     return 0;
1739   }
1740 
1741   if (mesh->runtime.deformed_only || index_dmcache == DMCACHE_ISCHILD) {
1742     /* for meshes that are either only deformed or for child particles, the
1743      * index and fw do not require any mapping, so we can directly use it */
1744     if (from == PART_FROM_VERT) {
1745       if (index >= mesh->totvert) {
1746         return 0;
1747       }
1748 
1749       *mapindex = index;
1750     }
1751     else { /* FROM_FACE/FROM_VOLUME */
1752       if (index >= mesh->totface) {
1753         return 0;
1754       }
1755 
1756       *mapindex = index;
1757       copy_v4_v4(mapfw, fw);
1758     }
1759   }
1760   else {
1761     /* for other meshes that have been modified, we try to map the particle
1762      * to their new location, which means a different index, and for faces
1763      * also a new face interpolation weights */
1764     if (from == PART_FROM_VERT) {
1765       if (index_dmcache == DMCACHE_NOTFOUND || index_dmcache >= mesh->totvert) {
1766         return 0;
1767       }
1768 
1769       *mapindex = index_dmcache;
1770     }
1771     else { /* FROM_FACE/FROM_VOLUME */
1772            /* find a face on the derived mesh that uses this face */
1773       MFace *mface;
1774       OrigSpaceFace *osface;
1775       int i;
1776 
1777       i = index_dmcache;
1778 
1779       if (i == DMCACHE_NOTFOUND || i >= mesh->totface) {
1780         return 0;
1781       }
1782 
1783       *mapindex = i;
1784 
1785       /* modify the original weights to become
1786        * weights for the derived mesh face */
1787       osface = CustomData_get_layer(&mesh->fdata, CD_ORIGSPACE);
1788       mface = &mesh->mface[i];
1789 
1790       if (osface == NULL) {
1791         mapfw[0] = mapfw[1] = mapfw[2] = mapfw[3] = 0.0f;
1792       }
1793       else {
1794         psys_origspace_to_w(&osface[i], mface->v4, fw, mapfw);
1795       }
1796     }
1797   }
1798 
1799   return 1;
1800 }
1801 
1802 /* interprets particle data to get a point on a mesh in object space */
psys_particle_on_dm(Mesh * mesh_final,int from,int index,int index_dmcache,const float fw[4],float foffset,float vec[3],float nor[3],float utan[3],float vtan[3],float orco[3])1803 void psys_particle_on_dm(Mesh *mesh_final,
1804                          int from,
1805                          int index,
1806                          int index_dmcache,
1807                          const float fw[4],
1808                          float foffset,
1809                          float vec[3],
1810                          float nor[3],
1811                          float utan[3],
1812                          float vtan[3],
1813                          float orco[3])
1814 {
1815   float tmpnor[3], mapfw[4];
1816   float(*orcodata)[3];
1817   int mapindex;
1818 
1819   if (!psys_map_index_on_dm(
1820           mesh_final, from, index, index_dmcache, fw, foffset, &mapindex, mapfw)) {
1821     if (vec) {
1822       vec[0] = vec[1] = vec[2] = 0.0;
1823     }
1824     if (nor) {
1825       nor[0] = nor[1] = 0.0;
1826       nor[2] = 1.0;
1827     }
1828     if (orco) {
1829       orco[0] = orco[1] = orco[2] = 0.0;
1830     }
1831     if (utan) {
1832       utan[0] = utan[1] = utan[2] = 0.0;
1833     }
1834     if (vtan) {
1835       vtan[0] = vtan[1] = vtan[2] = 0.0;
1836     }
1837 
1838     return;
1839   }
1840 
1841   orcodata = CustomData_get_layer(&mesh_final->vdata, CD_ORCO);
1842 
1843   if (from == PART_FROM_VERT) {
1844     copy_v3_v3(vec, mesh_final->mvert[mapindex].co);
1845 
1846     if (nor) {
1847       normal_short_to_float_v3(nor, mesh_final->mvert[mapindex].no);
1848       normalize_v3(nor);
1849     }
1850 
1851     if (orco) {
1852       if (orcodata) {
1853         copy_v3_v3(orco, orcodata[mapindex]);
1854       }
1855       else {
1856         copy_v3_v3(orco, vec);
1857       }
1858     }
1859 
1860     if (utan && vtan) {
1861       utan[0] = utan[1] = utan[2] = 0.0f;
1862       vtan[0] = vtan[1] = vtan[2] = 0.0f;
1863     }
1864   }
1865   else { /* PART_FROM_FACE / PART_FROM_VOLUME */
1866     MFace *mface;
1867     MTFace *mtface;
1868     MVert *mvert;
1869 
1870     mface = &mesh_final->mface[mapindex];
1871     mvert = mesh_final->mvert;
1872     mtface = mesh_final->mtface;
1873 
1874     if (mtface) {
1875       mtface += mapindex;
1876     }
1877 
1878     if (from == PART_FROM_VOLUME) {
1879       psys_interpolate_face(mvert, mface, mtface, orcodata, mapfw, vec, tmpnor, utan, vtan, orco);
1880       if (nor) {
1881         copy_v3_v3(nor, tmpnor);
1882       }
1883 
1884       /* XXX Why not normalize tmpnor before copying it into nor??? -- mont29 */
1885       normalize_v3(tmpnor);
1886 
1887       mul_v3_fl(tmpnor, -foffset);
1888       add_v3_v3(vec, tmpnor);
1889     }
1890     else {
1891       psys_interpolate_face(mvert, mface, mtface, orcodata, mapfw, vec, nor, utan, vtan, orco);
1892     }
1893   }
1894 }
1895 
psys_particle_value_from_verts(Mesh * mesh,short from,ParticleData * pa,float * values)1896 float psys_particle_value_from_verts(Mesh *mesh, short from, ParticleData *pa, float *values)
1897 {
1898   float mapfw[4];
1899   int mapindex;
1900 
1901   if (!psys_map_index_on_dm(
1902           mesh, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, &mapindex, mapfw)) {
1903     return 0.0f;
1904   }
1905 
1906   return psys_interpolate_value_from_verts(mesh, from, mapindex, mapfw, values);
1907 }
1908 
psys_get_modifier(Object * ob,ParticleSystem * psys)1909 ParticleSystemModifierData *psys_get_modifier(Object *ob, ParticleSystem *psys)
1910 {
1911   ModifierData *md;
1912   ParticleSystemModifierData *psmd;
1913 
1914   for (md = ob->modifiers.first; md; md = md->next) {
1915     if (md->type == eModifierType_ParticleSystem) {
1916       psmd = (ParticleSystemModifierData *)md;
1917       if (psmd->psys == psys) {
1918         return psmd;
1919       }
1920     }
1921   }
1922   return NULL;
1923 }
1924 /************************************************/
1925 /*          Particles on a shape                */
1926 /************************************************/
1927 /* ready for future use */
psys_particle_on_shape(int UNUSED (distr),int UNUSED (index),float * UNUSED (fuv),float vec[3],float nor[3],float utan[3],float vtan[3],float orco[3])1928 static void psys_particle_on_shape(int UNUSED(distr),
1929                                    int UNUSED(index),
1930                                    float *UNUSED(fuv),
1931                                    float vec[3],
1932                                    float nor[3],
1933                                    float utan[3],
1934                                    float vtan[3],
1935                                    float orco[3])
1936 {
1937   /* TODO */
1938   const float zerovec[3] = {0.0f, 0.0f, 0.0f};
1939   if (vec) {
1940     copy_v3_v3(vec, zerovec);
1941   }
1942   if (nor) {
1943     copy_v3_v3(nor, zerovec);
1944   }
1945   if (utan) {
1946     copy_v3_v3(utan, zerovec);
1947   }
1948   if (vtan) {
1949     copy_v3_v3(vtan, zerovec);
1950   }
1951   if (orco) {
1952     copy_v3_v3(orco, zerovec);
1953   }
1954 }
1955 /************************************************/
1956 /*          Particles on emitter                */
1957 /************************************************/
1958 
psys_emitter_customdata_mask(ParticleSystem * psys,CustomData_MeshMasks * r_cddata_masks)1959 void psys_emitter_customdata_mask(ParticleSystem *psys, CustomData_MeshMasks *r_cddata_masks)
1960 {
1961   MTex *mtex;
1962   int i;
1963 
1964   if (!psys->part) {
1965     return;
1966   }
1967 
1968   for (i = 0; i < MAX_MTEX; i++) {
1969     mtex = psys->part->mtex[i];
1970     if (mtex && mtex->mapto && (mtex->texco & TEXCO_UV)) {
1971       r_cddata_masks->fmask |= CD_MASK_MTFACE;
1972     }
1973   }
1974 
1975   if (psys->part->tanfac != 0.0f) {
1976     r_cddata_masks->fmask |= CD_MASK_MTFACE;
1977   }
1978 
1979   /* ask for vertexgroups if we need them */
1980   for (i = 0; i < PSYS_TOT_VG; i++) {
1981     if (psys->vgroup[i]) {
1982       r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
1983       break;
1984     }
1985   }
1986 
1987   /* particles only need this if they are after a non deform modifier, and
1988    * the modifier stack will only create them in that case. */
1989   r_cddata_masks->lmask |= CD_MASK_ORIGSPACE_MLOOP;
1990   /* XXX Check we do need all those? */
1991   r_cddata_masks->vmask |= CD_MASK_ORIGINDEX;
1992   r_cddata_masks->emask |= CD_MASK_ORIGINDEX;
1993   r_cddata_masks->pmask |= CD_MASK_ORIGINDEX;
1994 
1995   r_cddata_masks->vmask |= CD_MASK_ORCO;
1996 }
1997 
psys_particle_on_emitter(ParticleSystemModifierData * psmd,int from,int index,int index_dmcache,float fuv[4],float foffset,float vec[3],float nor[3],float utan[3],float vtan[3],float orco[3])1998 void psys_particle_on_emitter(ParticleSystemModifierData *psmd,
1999                               int from,
2000                               int index,
2001                               int index_dmcache,
2002                               float fuv[4],
2003                               float foffset,
2004                               float vec[3],
2005                               float nor[3],
2006                               float utan[3],
2007                               float vtan[3],
2008                               float orco[3])
2009 {
2010   if (psmd && psmd->mesh_final) {
2011     if (psmd->psys->part->distr == PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT) {
2012       if (vec) {
2013         copy_v3_v3(vec, fuv);
2014       }
2015 
2016       if (orco) {
2017         copy_v3_v3(orco, fuv);
2018       }
2019       return;
2020     }
2021     /* we cant use the num_dmcache */
2022     psys_particle_on_dm(
2023         psmd->mesh_final, from, index, index_dmcache, fuv, foffset, vec, nor, utan, vtan, orco);
2024   }
2025   else {
2026     psys_particle_on_shape(from, index, fuv, vec, nor, utan, vtan, orco);
2027   }
2028 }
2029 /************************************************/
2030 /*          Path Cache                          */
2031 /************************************************/
2032 
precalc_guides(ParticleSimulationData * sim,ListBase * effectors)2033 void precalc_guides(ParticleSimulationData *sim, ListBase *effectors)
2034 {
2035   EffectedPoint point;
2036   ParticleKey state;
2037   EffectorData efd;
2038   EffectorCache *eff;
2039   ParticleSystem *psys = sim->psys;
2040   EffectorWeights *weights = sim->psys->part->effector_weights;
2041   GuideEffectorData *data;
2042   PARTICLE_P;
2043 
2044   if (!effectors) {
2045     return;
2046   }
2047 
2048   LOOP_PARTICLES
2049   {
2050     psys_particle_on_emitter(sim->psmd,
2051                              sim->psys->part->from,
2052                              pa->num,
2053                              pa->num_dmcache,
2054                              pa->fuv,
2055                              pa->foffset,
2056                              state.co,
2057                              0,
2058                              0,
2059                              0,
2060                              0);
2061 
2062     mul_m4_v3(sim->ob->obmat, state.co);
2063     mul_mat3_m4_v3(sim->ob->obmat, state.vel);
2064 
2065     pd_point_from_particle(sim, pa, &state, &point);
2066 
2067     for (eff = effectors->first; eff; eff = eff->next) {
2068       if (eff->pd->forcefield != PFIELD_GUIDE) {
2069         continue;
2070       }
2071 
2072       if (!eff->guide_data) {
2073         eff->guide_data = MEM_callocN(sizeof(GuideEffectorData) * psys->totpart,
2074                                       "GuideEffectorData");
2075       }
2076 
2077       data = eff->guide_data + p;
2078 
2079       sub_v3_v3v3(efd.vec_to_point, state.co, eff->guide_loc);
2080       copy_v3_v3(efd.nor, eff->guide_dir);
2081       efd.distance = len_v3(efd.vec_to_point);
2082 
2083       copy_v3_v3(data->vec_to_point, efd.vec_to_point);
2084       data->strength = effector_falloff(eff, &efd, &point, weights);
2085     }
2086   }
2087 }
2088 
do_guides(Depsgraph * depsgraph,ParticleSettings * part,ListBase * effectors,ParticleKey * state,int index,float time)2089 int do_guides(Depsgraph *depsgraph,
2090               ParticleSettings *part,
2091               ListBase *effectors,
2092               ParticleKey *state,
2093               int index,
2094               float time)
2095 {
2096   CurveMapping *clumpcurve = (part->child_flag & PART_CHILD_USE_CLUMP_CURVE) ? part->clumpcurve :
2097                                                                                NULL;
2098   CurveMapping *roughcurve = (part->child_flag & PART_CHILD_USE_ROUGH_CURVE) ? part->roughcurve :
2099                                                                                NULL;
2100   EffectorCache *eff;
2101   PartDeflect *pd;
2102   Curve *cu;
2103   GuideEffectorData *data;
2104 
2105   float effect[3] = {0.0f, 0.0f, 0.0f}, veffect[3] = {0.0f, 0.0f, 0.0f};
2106   float guidevec[4], guidedir[3], rot2[4], temp[3];
2107   float guidetime, radius, weight, angle, totstrength = 0.0f;
2108   float vec_to_point[3];
2109 
2110   if (effectors) {
2111     for (eff = effectors->first; eff; eff = eff->next) {
2112       pd = eff->pd;
2113 
2114       if (pd->forcefield != PFIELD_GUIDE) {
2115         continue;
2116       }
2117 
2118       data = eff->guide_data + index;
2119 
2120       if (data->strength <= 0.0f) {
2121         continue;
2122       }
2123 
2124       guidetime = time / (1.0f - pd->free_end);
2125 
2126       if (guidetime > 1.0f) {
2127         continue;
2128       }
2129 
2130       cu = (Curve *)eff->ob->data;
2131 
2132       if (pd->flag & PFIELD_GUIDE_PATH_ADD) {
2133         if (where_on_path(
2134                 eff->ob, data->strength * guidetime, guidevec, guidedir, NULL, &radius, &weight) ==
2135             0) {
2136           return 0;
2137         }
2138       }
2139       else {
2140         if (where_on_path(eff->ob, guidetime, guidevec, guidedir, NULL, &radius, &weight) == 0) {
2141           return 0;
2142         }
2143       }
2144 
2145       mul_m4_v3(eff->ob->obmat, guidevec);
2146       mul_mat3_m4_v3(eff->ob->obmat, guidedir);
2147 
2148       normalize_v3(guidedir);
2149 
2150       copy_v3_v3(vec_to_point, data->vec_to_point);
2151 
2152       if (guidetime != 0.0f) {
2153         /* curve direction */
2154         cross_v3_v3v3(temp, eff->guide_dir, guidedir);
2155         angle = dot_v3v3(eff->guide_dir, guidedir) / (len_v3(eff->guide_dir));
2156         angle = saacos(angle);
2157         axis_angle_to_quat(rot2, temp, angle);
2158         mul_qt_v3(rot2, vec_to_point);
2159 
2160         /* curve tilt */
2161         axis_angle_to_quat(rot2, guidedir, guidevec[3] - eff->guide_loc[3]);
2162         mul_qt_v3(rot2, vec_to_point);
2163       }
2164 
2165       /* curve taper */
2166       if (cu->taperobj) {
2167         mul_v3_fl(vec_to_point,
2168                   BKE_displist_calc_taper(depsgraph,
2169                                           eff->scene,
2170                                           cu->taperobj,
2171                                           (int)(data->strength * guidetime * 100.0f),
2172                                           100));
2173       }
2174       else { /* curve size*/
2175         if (cu->flag & CU_PATH_RADIUS) {
2176           mul_v3_fl(vec_to_point, radius);
2177         }
2178       }
2179 
2180       if (clumpcurve) {
2181         BKE_curvemapping_changed_all(clumpcurve);
2182       }
2183       if (roughcurve) {
2184         BKE_curvemapping_changed_all(roughcurve);
2185       }
2186 
2187       {
2188         ParticleKey key;
2189         const float par_co[3] = {0.0f, 0.0f, 0.0f};
2190         const float par_vel[3] = {0.0f, 0.0f, 0.0f};
2191         const float par_rot[4] = {1.0f, 0.0f, 0.0f, 0.0f};
2192         const float orco_offset[3] = {0.0f, 0.0f, 0.0f};
2193 
2194         copy_v3_v3(key.co, vec_to_point);
2195         do_kink(&key,
2196                 par_co,
2197                 par_vel,
2198                 par_rot,
2199                 guidetime,
2200                 pd->kink_freq,
2201                 pd->kink_shape,
2202                 pd->kink_amp,
2203                 0.f,
2204                 pd->kink,
2205                 pd->kink_axis,
2206                 0,
2207                 0);
2208         do_clump(&key,
2209                  par_co,
2210                  guidetime,
2211                  orco_offset,
2212                  pd->clump_fac,
2213                  pd->clump_pow,
2214                  1.0f,
2215                  part->child_flag & PART_CHILD_USE_CLUMP_NOISE,
2216                  part->clump_noise_size,
2217                  clumpcurve);
2218         copy_v3_v3(vec_to_point, key.co);
2219       }
2220 
2221       add_v3_v3(vec_to_point, guidevec);
2222 
2223       // sub_v3_v3v3(pa_loc, pa_loc, pa_zero);
2224       madd_v3_v3fl(effect, vec_to_point, data->strength);
2225       madd_v3_v3fl(veffect, guidedir, data->strength);
2226       totstrength += data->strength;
2227 
2228       if (pd->flag & PFIELD_GUIDE_PATH_WEIGHT) {
2229         totstrength *= weight;
2230       }
2231     }
2232   }
2233 
2234   if (totstrength != 0.0f) {
2235     if (totstrength > 1.0f) {
2236       mul_v3_fl(effect, 1.0f / totstrength);
2237     }
2238     CLAMP(totstrength, 0.0f, 1.0f);
2239     // add_v3_v3(effect, pa_zero);
2240     interp_v3_v3v3(state->co, state->co, effect, totstrength);
2241 
2242     normalize_v3(veffect);
2243     mul_v3_fl(veffect, len_v3(state->vel));
2244     copy_v3_v3(state->vel, veffect);
2245     return 1;
2246   }
2247   return 0;
2248 }
2249 
do_path_effectors(ParticleSimulationData * sim,int i,ParticleCacheKey * ca,int k,int steps,float * UNUSED (rootco),float effector,float UNUSED (dfra),float UNUSED (cfra),float * length,float * vec)2250 static void do_path_effectors(ParticleSimulationData *sim,
2251                               int i,
2252                               ParticleCacheKey *ca,
2253                               int k,
2254                               int steps,
2255                               float *UNUSED(rootco),
2256                               float effector,
2257                               float UNUSED(dfra),
2258                               float UNUSED(cfra),
2259                               float *length,
2260                               float *vec)
2261 {
2262   float force[3] = {0.0f, 0.0f, 0.0f};
2263   ParticleKey eff_key;
2264   EffectedPoint epoint;
2265 
2266   /* Don't apply effectors for dynamic hair, otherwise the effectors don't get applied twice. */
2267   if (sim->psys->flag & PSYS_HAIR_DYNAMICS) {
2268     return;
2269   }
2270 
2271   copy_v3_v3(eff_key.co, (ca - 1)->co);
2272   copy_v3_v3(eff_key.vel, (ca - 1)->vel);
2273   copy_qt_qt(eff_key.rot, (ca - 1)->rot);
2274 
2275   pd_point_from_particle(sim, sim->psys->particles + i, &eff_key, &epoint);
2276   BKE_effectors_apply(sim->psys->effectors,
2277                       sim->colliders,
2278                       sim->psys->part->effector_weights,
2279                       &epoint,
2280                       force,
2281                       NULL,
2282                       NULL);
2283 
2284   mul_v3_fl(force,
2285             effector * powf((float)k / (float)steps, 100.0f * sim->psys->part->eff_hair) /
2286                 (float)steps);
2287 
2288   add_v3_v3(force, vec);
2289 
2290   normalize_v3(force);
2291 
2292   if (k < steps) {
2293     sub_v3_v3v3(vec, (ca + 1)->co, ca->co);
2294   }
2295 
2296   madd_v3_v3v3fl(ca->co, (ca - 1)->co, force, *length);
2297 
2298   if (k < steps) {
2299     *length = len_v3(vec);
2300   }
2301 }
offset_child(ChildParticle * cpa,ParticleKey * par,float * par_rot,ParticleKey * child,float flat,float radius)2302 static void offset_child(ChildParticle *cpa,
2303                          ParticleKey *par,
2304                          float *par_rot,
2305                          ParticleKey *child,
2306                          float flat,
2307                          float radius)
2308 {
2309   copy_v3_v3(child->co, cpa->fuv);
2310   mul_v3_fl(child->co, radius);
2311 
2312   child->co[0] *= flat;
2313 
2314   copy_v3_v3(child->vel, par->vel);
2315 
2316   if (par_rot) {
2317     mul_qt_v3(par_rot, child->co);
2318     copy_qt_qt(child->rot, par_rot);
2319   }
2320   else {
2321     unit_qt(child->rot);
2322   }
2323 
2324   add_v3_v3(child->co, par->co);
2325 }
psys_cache_vgroup(Mesh * mesh,ParticleSystem * psys,int vgroup)2326 float *psys_cache_vgroup(Mesh *mesh, ParticleSystem *psys, int vgroup)
2327 {
2328   float *vg = 0;
2329 
2330   if (vgroup < 0) {
2331     /* hair dynamics pinning vgroup */
2332   }
2333   else if (psys->vgroup[vgroup]) {
2334     MDeformVert *dvert = mesh->dvert;
2335     if (dvert) {
2336       int totvert = mesh->totvert, i;
2337       vg = MEM_callocN(sizeof(float) * totvert, "vg_cache");
2338       if (psys->vg_neg & (1 << vgroup)) {
2339         for (i = 0; i < totvert; i++) {
2340           vg[i] = 1.0f - BKE_defvert_find_weight(&dvert[i], psys->vgroup[vgroup] - 1);
2341         }
2342       }
2343       else {
2344         for (i = 0; i < totvert; i++) {
2345           vg[i] = BKE_defvert_find_weight(&dvert[i], psys->vgroup[vgroup] - 1);
2346         }
2347       }
2348     }
2349   }
2350   return vg;
2351 }
psys_find_parents(ParticleSimulationData * sim,const bool use_render_params)2352 void psys_find_parents(ParticleSimulationData *sim, const bool use_render_params)
2353 {
2354   ParticleSystem *psys = sim->psys;
2355   ParticleSettings *part = sim->psys->part;
2356   KDTree_3d *tree;
2357   ChildParticle *cpa;
2358   ParticleTexture ptex;
2359   int p, totparent, totchild = sim->psys->totchild;
2360   float co[3], orco[3];
2361   int from = PART_FROM_FACE;
2362   totparent = (int)(totchild * part->parents * 0.3f);
2363 
2364   if (use_render_params && part->child_nbr && part->ren_child_nbr) {
2365     totparent *= (float)part->child_nbr / (float)part->ren_child_nbr;
2366   }
2367 
2368   /* hard limit, workaround for it being ignored above */
2369   if (sim->psys->totpart < totparent) {
2370     totparent = sim->psys->totpart;
2371   }
2372 
2373   tree = BLI_kdtree_3d_new(totparent);
2374 
2375   for (p = 0, cpa = sim->psys->child; p < totparent; p++, cpa++) {
2376     psys_particle_on_emitter(
2377         sim->psmd, from, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, co, 0, 0, 0, orco);
2378 
2379     /* Check if particle doesn't exist because of texture influence.
2380      * Insert only existing particles into kdtree. */
2381     get_cpa_texture(sim->psmd->mesh_final,
2382                     psys,
2383                     part,
2384                     psys->particles + cpa->pa[0],
2385                     p,
2386                     cpa->num,
2387                     cpa->fuv,
2388                     orco,
2389                     &ptex,
2390                     PAMAP_DENS | PAMAP_CHILD,
2391                     psys->cfra);
2392 
2393     if (ptex.exist >= psys_frand(psys, p + 24)) {
2394       BLI_kdtree_3d_insert(tree, p, orco);
2395     }
2396   }
2397 
2398   BLI_kdtree_3d_balance(tree);
2399 
2400   for (; p < totchild; p++, cpa++) {
2401     psys_particle_on_emitter(
2402         sim->psmd, from, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, co, 0, 0, 0, orco);
2403     cpa->parent = BLI_kdtree_3d_find_nearest(tree, orco, NULL);
2404   }
2405 
2406   BLI_kdtree_3d_free(tree);
2407 }
2408 
psys_thread_context_init_path(ParticleThreadContext * ctx,ParticleSimulationData * sim,Scene * scene,float cfra,const bool editupdate,const bool use_render_params)2409 static bool psys_thread_context_init_path(ParticleThreadContext *ctx,
2410                                           ParticleSimulationData *sim,
2411                                           Scene *scene,
2412                                           float cfra,
2413                                           const bool editupdate,
2414                                           const bool use_render_params)
2415 {
2416   ParticleSystem *psys = sim->psys;
2417   ParticleSettings *part = psys->part;
2418   int totparent = 0, between = 0;
2419   int segments = 1 << part->draw_step;
2420   int totchild = psys->totchild;
2421 
2422   psys_thread_context_init(ctx, sim);
2423 
2424   /*---start figuring out what is actually wanted---*/
2425   if (psys_in_edit_mode(sim->depsgraph, psys)) {
2426     ParticleEditSettings *pset = &scene->toolsettings->particle;
2427 
2428     if ((use_render_params == 0) &&
2429         (psys_orig_edit_get(psys) == NULL || pset->flag & PE_DRAW_PART) == 0) {
2430       totchild = 0;
2431     }
2432 
2433     segments = 1 << pset->draw_step;
2434   }
2435 
2436   if (totchild && part->childtype == PART_CHILD_FACES) {
2437     totparent = (int)(totchild * part->parents * 0.3f);
2438 
2439     if (use_render_params && part->child_nbr && part->ren_child_nbr) {
2440       totparent *= (float)part->child_nbr / (float)part->ren_child_nbr;
2441     }
2442 
2443     /* part->parents could still be 0 so we can't test with totparent */
2444     between = 1;
2445   }
2446 
2447   if (use_render_params) {
2448     segments = 1 << part->ren_step;
2449   }
2450   else {
2451     totchild = (int)((float)totchild * (float)part->disp / 100.0f);
2452   }
2453 
2454   totparent = MIN2(totparent, totchild);
2455 
2456   if (totchild == 0) {
2457     return false;
2458   }
2459 
2460   /* fill context values */
2461   ctx->between = between;
2462   ctx->segments = segments;
2463   if (ELEM(part->kink, PART_KINK_SPIRAL)) {
2464     ctx->extra_segments = max_ii(part->kink_extra_steps, 1);
2465   }
2466   else {
2467     ctx->extra_segments = 0;
2468   }
2469   ctx->totchild = totchild;
2470   ctx->totparent = totparent;
2471   ctx->parent_pass = 0;
2472   ctx->cfra = cfra;
2473   ctx->editupdate = editupdate;
2474 
2475   psys->lattice_deform_data = psys_create_lattice_deform_data(&ctx->sim);
2476 
2477   /* cache all relevant vertex groups if they exist */
2478   ctx->vg_length = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_LENGTH);
2479   ctx->vg_clump = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_CLUMP);
2480   ctx->vg_kink = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_KINK);
2481   ctx->vg_rough1 = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_ROUGH1);
2482   ctx->vg_rough2 = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_ROUGH2);
2483   ctx->vg_roughe = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_ROUGHE);
2484   ctx->vg_twist = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_TWIST);
2485   if (psys->part->flag & PART_CHILD_EFFECT) {
2486     ctx->vg_effector = psys_cache_vgroup(ctx->mesh, psys, PSYS_VG_EFFECTOR);
2487   }
2488 
2489   /* prepare curvemapping tables */
2490   if ((part->child_flag & PART_CHILD_USE_CLUMP_CURVE) && part->clumpcurve) {
2491     ctx->clumpcurve = BKE_curvemapping_copy(part->clumpcurve);
2492     BKE_curvemapping_changed_all(ctx->clumpcurve);
2493   }
2494   else {
2495     ctx->clumpcurve = NULL;
2496   }
2497   if ((part->child_flag & PART_CHILD_USE_ROUGH_CURVE) && part->roughcurve) {
2498     ctx->roughcurve = BKE_curvemapping_copy(part->roughcurve);
2499     BKE_curvemapping_changed_all(ctx->roughcurve);
2500   }
2501   else {
2502     ctx->roughcurve = NULL;
2503   }
2504   if ((part->child_flag & PART_CHILD_USE_TWIST_CURVE) && part->twistcurve) {
2505     ctx->twistcurve = BKE_curvemapping_copy(part->twistcurve);
2506     BKE_curvemapping_changed_all(ctx->twistcurve);
2507   }
2508   else {
2509     ctx->twistcurve = NULL;
2510   }
2511 
2512   return true;
2513 }
2514 
psys_task_init_path(ParticleTask * task,ParticleSimulationData * sim)2515 static void psys_task_init_path(ParticleTask *task, ParticleSimulationData *sim)
2516 {
2517   /* init random number generator */
2518   int seed = 31415926 + sim->psys->seed;
2519 
2520   task->rng_path = BLI_rng_new(seed);
2521 }
2522 
2523 /* note: this function must be thread safe, except for branching! */
psys_thread_create_path(ParticleTask * task,struct ChildParticle * cpa,ParticleCacheKey * child_keys,int i)2524 static void psys_thread_create_path(ParticleTask *task,
2525                                     struct ChildParticle *cpa,
2526                                     ParticleCacheKey *child_keys,
2527                                     int i)
2528 {
2529   ParticleThreadContext *ctx = task->ctx;
2530   Object *ob = ctx->sim.ob;
2531   ParticleSystem *psys = ctx->sim.psys;
2532   ParticleSettings *part = psys->part;
2533   ParticleCacheKey **cache = psys->childcache;
2534   PTCacheEdit *edit = psys_orig_edit_get(psys);
2535   ParticleCacheKey **pcache = psys_in_edit_mode(ctx->sim.depsgraph, psys) && edit ?
2536                                   edit->pathcache :
2537                                   psys->pathcache;
2538   ParticleCacheKey *child, *key[4];
2539   ParticleTexture ptex;
2540   float *cpa_fuv = 0, *par_rot = 0, rot[4];
2541   float orco[3], hairmat[4][4], dvec[3], off1[4][3], off2[4][3];
2542   float eff_length, eff_vec[3], weight[4];
2543   int k, cpa_num;
2544   short cpa_from;
2545 
2546   if (!pcache) {
2547     return;
2548   }
2549 
2550   if (ctx->between) {
2551     ParticleData *pa = psys->particles + cpa->pa[0];
2552     int w, needupdate;
2553     float foffset, wsum = 0.f;
2554     float co[3];
2555     float p_min = part->parting_min;
2556     float p_max = part->parting_max;
2557     /* Virtual parents don't work nicely with parting. */
2558     float p_fac = part->parents > 0.f ? 0.f : part->parting_fac;
2559 
2560     if (ctx->editupdate) {
2561       needupdate = 0;
2562       w = 0;
2563       while (w < 4 && cpa->pa[w] >= 0) {
2564         if (edit->points[cpa->pa[w]].flag & PEP_EDIT_RECALC) {
2565           needupdate = 1;
2566           break;
2567         }
2568         w++;
2569       }
2570 
2571       if (!needupdate) {
2572         return;
2573       }
2574 
2575       memset(child_keys, 0, sizeof(*child_keys) * (ctx->segments + 1));
2576     }
2577 
2578     /* get parent paths */
2579     for (w = 0; w < 4; w++) {
2580       if (cpa->pa[w] >= 0) {
2581         key[w] = pcache[cpa->pa[w]];
2582         weight[w] = cpa->w[w];
2583       }
2584       else {
2585         key[w] = pcache[0];
2586         weight[w] = 0.f;
2587       }
2588     }
2589 
2590     /* modify weights to create parting */
2591     if (p_fac > 0.f) {
2592       const ParticleCacheKey *key_0_last = pcache_key_segment_endpoint_safe(key[0]);
2593       for (w = 0; w < 4; w++) {
2594         if (w && (weight[w] > 0.f)) {
2595           const ParticleCacheKey *key_w_last = pcache_key_segment_endpoint_safe(key[w]);
2596           float d;
2597           if (part->flag & PART_CHILD_LONG_HAIR) {
2598             /* For long hair use tip distance/root distance as parting
2599              * factor instead of root to tip angle. */
2600             float d1 = len_v3v3(key[0]->co, key[w]->co);
2601             float d2 = len_v3v3(key_0_last->co, key_w_last->co);
2602 
2603             d = d1 > 0.f ? d2 / d1 - 1.f : 10000.f;
2604           }
2605           else {
2606             float v1[3], v2[3];
2607             sub_v3_v3v3(v1, key_0_last->co, key[0]->co);
2608             sub_v3_v3v3(v2, key_w_last->co, key[w]->co);
2609             normalize_v3(v1);
2610             normalize_v3(v2);
2611 
2612             d = RAD2DEGF(saacos(dot_v3v3(v1, v2)));
2613           }
2614 
2615           if (p_max > p_min) {
2616             d = (d - p_min) / (p_max - p_min);
2617           }
2618           else {
2619             d = (d - p_min) <= 0.f ? 0.f : 1.f;
2620           }
2621 
2622           CLAMP(d, 0.f, 1.f);
2623 
2624           if (d > 0.f) {
2625             weight[w] *= (1.f - d);
2626           }
2627         }
2628         wsum += weight[w];
2629       }
2630       for (w = 0; w < 4; w++) {
2631         weight[w] /= wsum;
2632       }
2633 
2634       interp_v4_v4v4(weight, cpa->w, weight, p_fac);
2635     }
2636 
2637     /* get the original coordinates (orco) for texture usage */
2638     cpa_num = cpa->num;
2639 
2640     foffset = cpa->foffset;
2641     cpa_fuv = cpa->fuv;
2642     cpa_from = PART_FROM_FACE;
2643 
2644     psys_particle_on_emitter(
2645         ctx->sim.psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa->fuv, foffset, co, 0, 0, 0, orco);
2646 
2647     mul_m4_v3(ob->obmat, co);
2648 
2649     for (w = 0; w < 4; w++) {
2650       sub_v3_v3v3(off1[w], co, key[w]->co);
2651     }
2652 
2653     psys_mat_hair_to_global(ob, ctx->sim.psmd->mesh_final, psys->part->from, pa, hairmat);
2654   }
2655   else {
2656     ParticleData *pa = psys->particles + cpa->parent;
2657     float co[3];
2658     if (ctx->editupdate) {
2659       if (!(edit->points[cpa->parent].flag & PEP_EDIT_RECALC)) {
2660         return;
2661       }
2662 
2663       memset(child_keys, 0, sizeof(*child_keys) * (ctx->segments + 1));
2664     }
2665 
2666     /* get the parent path */
2667     key[0] = pcache[cpa->parent];
2668 
2669     /* get the original coordinates (orco) for texture usage */
2670     cpa_from = part->from;
2671 
2672     /*
2673      * NOTE: Should in theory be the same as:
2674      * cpa_num = psys_particle_dm_face_lookup(
2675      *        ctx->sim.psmd->dm_final,
2676      *        ctx->sim.psmd->dm_deformed,
2677      *        pa->num, pa->fuv,
2678      *        NULL);
2679      */
2680     cpa_num = (ELEM(pa->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND)) ? pa->num :
2681                                                                            pa->num_dmcache;
2682 
2683     /* XXX hack to avoid messed up particle num and subsequent crash (T40733) */
2684     if (cpa_num > ctx->sim.psmd->mesh_final->totface) {
2685       cpa_num = 0;
2686     }
2687     cpa_fuv = pa->fuv;
2688 
2689     psys_particle_on_emitter(ctx->sim.psmd,
2690                              cpa_from,
2691                              cpa_num,
2692                              DMCACHE_ISCHILD,
2693                              cpa_fuv,
2694                              pa->foffset,
2695                              co,
2696                              0,
2697                              0,
2698                              0,
2699                              orco);
2700 
2701     psys_mat_hair_to_global(ob, ctx->sim.psmd->mesh_final, psys->part->from, pa, hairmat);
2702   }
2703 
2704   child_keys->segments = ctx->segments;
2705 
2706   /* get different child parameters from textures & vgroups */
2707   get_child_modifier_parameters(part, ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex);
2708 
2709   if (ptex.exist < psys_frand(psys, i + 24)) {
2710     child_keys->segments = -1;
2711     return;
2712   }
2713 
2714   /* create the child path */
2715   for (k = 0, child = child_keys; k <= ctx->segments; k++, child++) {
2716     if (ctx->between) {
2717       int w = 0;
2718 
2719       zero_v3(child->co);
2720       zero_v3(child->vel);
2721       unit_qt(child->rot);
2722 
2723       for (w = 0; w < 4; w++) {
2724         copy_v3_v3(off2[w], off1[w]);
2725 
2726         if (part->flag & PART_CHILD_LONG_HAIR) {
2727           /* Use parent rotation (in addition to emission location) to determine child offset. */
2728           if (k) {
2729             mul_qt_v3((key[w] + k)->rot, off2[w]);
2730           }
2731 
2732           /* Fade the effect of rotation for even lengths in the end */
2733           project_v3_v3v3(dvec, off2[w], (key[w] + k)->vel);
2734           madd_v3_v3fl(off2[w], dvec, -(float)k / (float)ctx->segments);
2735         }
2736 
2737         add_v3_v3(off2[w], (key[w] + k)->co);
2738       }
2739 
2740       /* child position is the weighted sum of parent positions */
2741       interp_v3_v3v3v3v3(child->co, off2[0], off2[1], off2[2], off2[3], weight);
2742       interp_v3_v3v3v3v3(child->vel,
2743                          (key[0] + k)->vel,
2744                          (key[1] + k)->vel,
2745                          (key[2] + k)->vel,
2746                          (key[3] + k)->vel,
2747                          weight);
2748 
2749       copy_qt_qt(child->rot, (key[0] + k)->rot);
2750     }
2751     else {
2752       if (k) {
2753         mul_qt_qtqt(rot, (key[0] + k)->rot, key[0]->rot);
2754         par_rot = rot;
2755       }
2756       else {
2757         par_rot = key[0]->rot;
2758       }
2759       /* offset the child from the parent position */
2760       offset_child(cpa,
2761                    (ParticleKey *)(key[0] + k),
2762                    par_rot,
2763                    (ParticleKey *)child,
2764                    part->childflat,
2765                    part->childrad);
2766     }
2767 
2768     child->time = (float)k / (float)ctx->segments;
2769   }
2770 
2771   /* apply effectors */
2772   if (part->flag & PART_CHILD_EFFECT) {
2773     for (k = 0, child = child_keys; k <= ctx->segments; k++, child++) {
2774       if (k) {
2775         do_path_effectors(&ctx->sim,
2776                           cpa->pa[0],
2777                           child,
2778                           k,
2779                           ctx->segments,
2780                           child_keys->co,
2781                           ptex.effector,
2782                           0.0f,
2783                           ctx->cfra,
2784                           &eff_length,
2785                           eff_vec);
2786       }
2787       else {
2788         sub_v3_v3v3(eff_vec, (child + 1)->co, child->co);
2789         eff_length = len_v3(eff_vec);
2790       }
2791     }
2792   }
2793 
2794   {
2795     ParticleData *pa = NULL;
2796     ParticleCacheKey *par = NULL;
2797     float par_co[3];
2798     float par_orco[3];
2799 
2800     if (ctx->totparent) {
2801       if (i >= ctx->totparent) {
2802         pa = &psys->particles[cpa->parent];
2803         /* this is now threadsafe, virtual parents are calculated before rest of children */
2804         BLI_assert(cpa->parent < psys->totchildcache);
2805         par = cache[cpa->parent];
2806       }
2807     }
2808     else if (cpa->parent >= 0) {
2809       pa = &psys->particles[cpa->parent];
2810       par = pcache[cpa->parent];
2811 
2812       /* If particle is non-existing, try to pick a viable parent from particles
2813        * used for interpolation. */
2814       for (k = 0; k < 4 && pa && (pa->flag & PARS_UNEXIST); k++) {
2815         if (cpa->pa[k] >= 0) {
2816           pa = &psys->particles[cpa->pa[k]];
2817           par = pcache[cpa->pa[k]];
2818         }
2819       }
2820 
2821       if (pa->flag & PARS_UNEXIST) {
2822         pa = NULL;
2823       }
2824     }
2825 
2826     if (pa) {
2827       ListBase modifiers;
2828       BLI_listbase_clear(&modifiers);
2829 
2830       psys_particle_on_emitter(ctx->sim.psmd,
2831                                part->from,
2832                                pa->num,
2833                                pa->num_dmcache,
2834                                pa->fuv,
2835                                pa->foffset,
2836                                par_co,
2837                                NULL,
2838                                NULL,
2839                                NULL,
2840                                par_orco);
2841 
2842       psys_apply_child_modifiers(
2843           ctx, &modifiers, cpa, &ptex, orco, hairmat, child_keys, par, par_orco);
2844     }
2845     else {
2846       zero_v3(par_orco);
2847     }
2848   }
2849 
2850   /* Hide virtual parents */
2851   if (i < ctx->totparent) {
2852     child_keys->segments = -1;
2853   }
2854 }
2855 
exec_child_path_cache(TaskPool * __restrict UNUSED (pool),void * taskdata)2856 static void exec_child_path_cache(TaskPool *__restrict UNUSED(pool), void *taskdata)
2857 {
2858   ParticleTask *task = taskdata;
2859   ParticleThreadContext *ctx = task->ctx;
2860   ParticleSystem *psys = ctx->sim.psys;
2861   ParticleCacheKey **cache = psys->childcache;
2862   ChildParticle *cpa;
2863   int i;
2864 
2865   cpa = psys->child + task->begin;
2866   for (i = task->begin; i < task->end; i++, cpa++) {
2867     BLI_assert(i < psys->totchildcache);
2868     psys_thread_create_path(task, cpa, cache[i], i);
2869   }
2870 }
2871 
psys_cache_child_paths(ParticleSimulationData * sim,float cfra,const bool editupdate,const bool use_render_params)2872 void psys_cache_child_paths(ParticleSimulationData *sim,
2873                             float cfra,
2874                             const bool editupdate,
2875                             const bool use_render_params)
2876 {
2877   TaskPool *task_pool;
2878   ParticleThreadContext ctx;
2879   ParticleTask *tasks_parent, *tasks_child;
2880   int numtasks_parent, numtasks_child;
2881   int i, totchild, totparent;
2882 
2883   if (sim->psys->flag & PSYS_GLOBAL_HAIR) {
2884     return;
2885   }
2886 
2887   /* create a task pool for child path tasks */
2888   if (!psys_thread_context_init_path(&ctx, sim, sim->scene, cfra, editupdate, use_render_params)) {
2889     return;
2890   }
2891 
2892   task_pool = BLI_task_pool_create(&ctx, TASK_PRIORITY_LOW);
2893   totchild = ctx.totchild;
2894   totparent = ctx.totparent;
2895 
2896   if (editupdate && sim->psys->childcache && totchild == sim->psys->totchildcache) {
2897     /* just overwrite the existing cache */
2898   }
2899   else {
2900     /* clear out old and create new empty path cache */
2901     free_child_path_cache(sim->psys);
2902 
2903     sim->psys->childcache = psys_alloc_path_cache_buffers(
2904         &sim->psys->childcachebufs, totchild, ctx.segments + ctx.extra_segments + 1);
2905     sim->psys->totchildcache = totchild;
2906   }
2907 
2908   /* cache parent paths */
2909   ctx.parent_pass = 1;
2910   psys_tasks_create(&ctx, 0, totparent, &tasks_parent, &numtasks_parent);
2911   for (i = 0; i < numtasks_parent; i++) {
2912     ParticleTask *task = &tasks_parent[i];
2913 
2914     psys_task_init_path(task, sim);
2915     BLI_task_pool_push(task_pool, exec_child_path_cache, task, false, NULL);
2916   }
2917   BLI_task_pool_work_and_wait(task_pool);
2918 
2919   /* cache child paths */
2920   ctx.parent_pass = 0;
2921   psys_tasks_create(&ctx, totparent, totchild, &tasks_child, &numtasks_child);
2922   for (i = 0; i < numtasks_child; i++) {
2923     ParticleTask *task = &tasks_child[i];
2924 
2925     psys_task_init_path(task, sim);
2926     BLI_task_pool_push(task_pool, exec_child_path_cache, task, false, NULL);
2927   }
2928   BLI_task_pool_work_and_wait(task_pool);
2929 
2930   BLI_task_pool_free(task_pool);
2931 
2932   psys_tasks_free(tasks_parent, numtasks_parent);
2933   psys_tasks_free(tasks_child, numtasks_child);
2934 
2935   psys_thread_context_free(&ctx);
2936 }
2937 
2938 /* figure out incremental rotations along path starting from unit quat */
cache_key_incremental_rotation(ParticleCacheKey * key0,ParticleCacheKey * key1,ParticleCacheKey * key2,float * prev_tangent,int i)2939 static void cache_key_incremental_rotation(ParticleCacheKey *key0,
2940                                            ParticleCacheKey *key1,
2941                                            ParticleCacheKey *key2,
2942                                            float *prev_tangent,
2943                                            int i)
2944 {
2945   float cosangle, angle, tangent[3], normal[3], q[4];
2946 
2947   switch (i) {
2948     case 0:
2949       /* start from second key */
2950       break;
2951     case 1:
2952       /* calculate initial tangent for incremental rotations */
2953       sub_v3_v3v3(prev_tangent, key0->co, key1->co);
2954       normalize_v3(prev_tangent);
2955       unit_qt(key1->rot);
2956       break;
2957     default:
2958       sub_v3_v3v3(tangent, key0->co, key1->co);
2959       normalize_v3(tangent);
2960 
2961       cosangle = dot_v3v3(tangent, prev_tangent);
2962 
2963       /* note we do the comparison on cosangle instead of
2964        * angle, since floating point accuracy makes it give
2965        * different results across platforms */
2966       if (cosangle > 0.999999f) {
2967         copy_v4_v4(key1->rot, key2->rot);
2968       }
2969       else {
2970         angle = saacos(cosangle);
2971         cross_v3_v3v3(normal, prev_tangent, tangent);
2972         axis_angle_to_quat(q, normal, angle);
2973         mul_qt_qtqt(key1->rot, q, key2->rot);
2974       }
2975 
2976       copy_v3_v3(prev_tangent, tangent);
2977   }
2978 }
2979 
2980 /**
2981  * Calculates paths ready for drawing/rendering
2982  * - Useful for making use of opengl vertex arrays for super fast strand drawing.
2983  * - Makes child strands possible and creates them too into the cache.
2984  * - Cached path data is also used to determine cut position for the editmode tool. */
psys_cache_paths(ParticleSimulationData * sim,float cfra,const bool use_render_params)2985 void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_render_params)
2986 {
2987   PARTICLE_PSMD;
2988   ParticleEditSettings *pset = &sim->scene->toolsettings->particle;
2989   ParticleSystem *psys = sim->psys;
2990   ParticleSettings *part = psys->part;
2991   ParticleCacheKey *ca, **cache;
2992 
2993   Mesh *hair_mesh = (psys->part->type == PART_HAIR && psys->flag & PSYS_HAIR_DYNAMICS) ?
2994                         psys->hair_out_mesh :
2995                         NULL;
2996 
2997   ParticleKey result;
2998 
2999   Material *ma;
3000   ParticleInterpolationData pind;
3001   ParticleTexture ptex;
3002 
3003   PARTICLE_P;
3004 
3005   float birthtime = 0.0, dietime = 0.0;
3006   float t, time = 0.0, dfra = 1.0 /* , frs_sec = sim->scene->r.frs_sec*/ /*UNUSED*/;
3007   float col[4] = {0.5f, 0.5f, 0.5f, 1.0f};
3008   float prev_tangent[3] = {0.0f, 0.0f, 0.0f}, hairmat[4][4];
3009   float rotmat[3][3];
3010   int k;
3011   int segments = (int)pow(2.0, (double)((use_render_params) ? part->ren_step : part->draw_step));
3012   int totpart = psys->totpart;
3013   float length, vec[3];
3014   float *vg_effector = NULL;
3015   float *vg_length = NULL, pa_length = 1.0f;
3016   int keyed, baked;
3017 
3018   /* we don't have anything valid to create paths from so let's quit here */
3019   if ((psys->flag & PSYS_HAIR_DONE || psys->flag & PSYS_KEYED || psys->pointcache) == 0) {
3020     return;
3021   }
3022 
3023   if (psys_in_edit_mode(sim->depsgraph, psys)) {
3024     if ((psys->edit == NULL || pset->flag & PE_DRAW_PART) == 0) {
3025       return;
3026     }
3027   }
3028 
3029   keyed = psys->flag & PSYS_KEYED;
3030   baked = psys->pointcache->mem_cache.first && psys->part->type != PART_HAIR;
3031 
3032   /* clear out old and create new empty path cache */
3033   psys_free_path_cache(psys, psys->edit);
3034   cache = psys->pathcache = psys_alloc_path_cache_buffers(
3035       &psys->pathcachebufs, totpart, segments + 1);
3036 
3037   psys->lattice_deform_data = psys_create_lattice_deform_data(sim);
3038   ma = BKE_object_material_get(sim->ob, psys->part->omat);
3039   if (ma && (psys->part->draw_col == PART_DRAW_COL_MAT)) {
3040     copy_v3_v3(col, &ma->r);
3041   }
3042 
3043   if ((psys->flag & PSYS_GLOBAL_HAIR) == 0) {
3044     if ((psys->part->flag & PART_CHILD_EFFECT) == 0) {
3045       vg_effector = psys_cache_vgroup(psmd->mesh_final, psys, PSYS_VG_EFFECTOR);
3046     }
3047 
3048     if (!psys->totchild) {
3049       vg_length = psys_cache_vgroup(psmd->mesh_final, psys, PSYS_VG_LENGTH);
3050     }
3051   }
3052 
3053   /* ensure we have tessfaces to be used for mapping */
3054   if (part->from != PART_FROM_VERT) {
3055     BKE_mesh_tessface_ensure(psmd->mesh_final);
3056   }
3057 
3058   /*---first main loop: create all actual particles' paths---*/
3059   LOOP_PARTICLES
3060   {
3061     if (!psys->totchild) {
3062       psys_get_texture(sim, pa, &ptex, PAMAP_LENGTH, 0.f);
3063       pa_length = ptex.length * (1.0f - part->randlength * psys_frand(psys, psys->seed + p));
3064       if (vg_length) {
3065         pa_length *= psys_particle_value_from_verts(psmd->mesh_final, part->from, pa, vg_length);
3066       }
3067     }
3068 
3069     pind.keyed = keyed;
3070     pind.cache = baked ? psys->pointcache : NULL;
3071     pind.epoint = NULL;
3072     pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE);
3073     pind.mesh = hair_mesh;
3074 
3075     memset(cache[p], 0, sizeof(*cache[p]) * (segments + 1));
3076 
3077     cache[p]->segments = segments;
3078 
3079     /*--get the first data points--*/
3080     init_particle_interpolation(sim->ob, sim->psys, pa, &pind);
3081 
3082     /* 'hairmat' is needed for non-hair particle too so we get proper rotations. */
3083     psys_mat_hair_to_global(sim->ob, psmd->mesh_final, psys->part->from, pa, hairmat);
3084     copy_v3_v3(rotmat[0], hairmat[2]);
3085     copy_v3_v3(rotmat[1], hairmat[1]);
3086     copy_v3_v3(rotmat[2], hairmat[0]);
3087 
3088     if (part->draw & PART_ABS_PATH_TIME) {
3089       birthtime = MAX2(pind.birthtime, part->path_start);
3090       dietime = MIN2(pind.dietime, part->path_end);
3091     }
3092     else {
3093       float tb = pind.birthtime;
3094       birthtime = tb + part->path_start * (pind.dietime - tb);
3095       dietime = tb + part->path_end * (pind.dietime - tb);
3096     }
3097 
3098     if (birthtime >= dietime) {
3099       cache[p]->segments = -1;
3100       continue;
3101     }
3102 
3103     dietime = birthtime + pa_length * (dietime - birthtime);
3104 
3105     /*--interpolate actual path from data points--*/
3106     for (k = 0, ca = cache[p]; k <= segments; k++, ca++) {
3107       time = (float)k / (float)segments;
3108       t = birthtime + time * (dietime - birthtime);
3109       result.time = -t;
3110       do_particle_interpolation(psys, p, pa, t, &pind, &result);
3111       copy_v3_v3(ca->co, result.co);
3112 
3113       /* dynamic hair is in object space */
3114       /* keyed and baked are already in global space */
3115       if (hair_mesh) {
3116         mul_m4_v3(sim->ob->obmat, ca->co);
3117       }
3118       else if (!keyed && !baked && !(psys->flag & PSYS_GLOBAL_HAIR)) {
3119         mul_m4_v3(hairmat, ca->co);
3120       }
3121 
3122       copy_v3_v3(ca->col, col);
3123     }
3124 
3125     if (part->type == PART_HAIR) {
3126       HairKey *hkey;
3127 
3128       for (k = 0, hkey = pa->hair; k < pa->totkey; k++, hkey++) {
3129         mul_v3_m4v3(hkey->world_co, hairmat, hkey->co);
3130       }
3131     }
3132 
3133     /*--modify paths and calculate rotation & velocity--*/
3134 
3135     if (!(psys->flag & PSYS_GLOBAL_HAIR)) {
3136       /* apply effectors */
3137       if ((psys->part->flag & PART_CHILD_EFFECT) == 0) {
3138         float effector = 1.0f;
3139         if (vg_effector) {
3140           effector *= psys_particle_value_from_verts(
3141               psmd->mesh_final, psys->part->from, pa, vg_effector);
3142         }
3143 
3144         sub_v3_v3v3(vec, (cache[p] + 1)->co, cache[p]->co);
3145         length = len_v3(vec);
3146 
3147         for (k = 1, ca = cache[p] + 1; k <= segments; k++, ca++) {
3148           do_path_effectors(
3149               sim, p, ca, k, segments, cache[p]->co, effector, dfra, cfra, &length, vec);
3150         }
3151       }
3152 
3153       /* apply guide curves to path data */
3154       if (sim->psys->effectors && (psys->part->flag & PART_CHILD_EFFECT) == 0) {
3155         for (k = 0, ca = cache[p]; k <= segments; k++, ca++) {
3156           /* ca is safe to cast, since only co and vel are used */
3157           do_guides(sim->depsgraph,
3158                     sim->psys->part,
3159                     sim->psys->effectors,
3160                     (ParticleKey *)ca,
3161                     p,
3162                     (float)k / (float)segments);
3163         }
3164       }
3165 
3166       /* lattices have to be calculated separately to avoid mixups between effector calculations */
3167       if (psys->lattice_deform_data) {
3168         for (k = 0, ca = cache[p]; k <= segments; k++, ca++) {
3169           BKE_lattice_deform_data_eval_co(
3170               psys->lattice_deform_data, ca->co, psys->lattice_strength);
3171         }
3172       }
3173     }
3174 
3175     /* finally do rotation & velocity */
3176     for (k = 1, ca = cache[p] + 1; k <= segments; k++, ca++) {
3177       cache_key_incremental_rotation(ca, ca - 1, ca - 2, prev_tangent, k);
3178 
3179       if (k == segments) {
3180         copy_qt_qt(ca->rot, (ca - 1)->rot);
3181       }
3182 
3183       /* set velocity */
3184       sub_v3_v3v3(ca->vel, ca->co, (ca - 1)->co);
3185 
3186       if (k == 1) {
3187         copy_v3_v3((ca - 1)->vel, ca->vel);
3188       }
3189 
3190       ca->time = (float)k / (float)segments;
3191     }
3192     /* First rotation is based on emitting face orientation.
3193      * This is way better than having flipping rotations resulting
3194      * from using a global axis as a rotation pole (vec_to_quat()).
3195      * It's not an ideal solution though since it disregards the
3196      * initial tangent, but taking that in to account will allow
3197      * the possibility of flipping again. -jahka
3198      */
3199     mat3_to_quat_is_ok(cache[p]->rot, rotmat);
3200   }
3201 
3202   psys->totcached = totpart;
3203 
3204   if (psys->lattice_deform_data) {
3205     BKE_lattice_deform_data_destroy(psys->lattice_deform_data);
3206     psys->lattice_deform_data = NULL;
3207   }
3208 
3209   if (vg_effector) {
3210     MEM_freeN(vg_effector);
3211   }
3212 
3213   if (vg_length) {
3214     MEM_freeN(vg_length);
3215   }
3216 }
3217 
3218 typedef struct CacheEditrPathsIterData {
3219   Object *object;
3220   PTCacheEdit *edit;
3221   ParticleSystemModifierData *psmd;
3222   ParticleData *pa;
3223   int segments;
3224   bool use_weight;
3225 } CacheEditrPathsIterData;
3226 
psys_cache_edit_paths_iter(void * __restrict iter_data_v,const int iter,const TaskParallelTLS * __restrict UNUSED (tls))3227 static void psys_cache_edit_paths_iter(void *__restrict iter_data_v,
3228                                        const int iter,
3229                                        const TaskParallelTLS *__restrict UNUSED(tls))
3230 {
3231   CacheEditrPathsIterData *iter_data = (CacheEditrPathsIterData *)iter_data_v;
3232   PTCacheEdit *edit = iter_data->edit;
3233   PTCacheEditPoint *point = &edit->points[iter];
3234   if (edit->totcached && !(point->flag & PEP_EDIT_RECALC)) {
3235     return;
3236   }
3237   if (point->totkey == 0) {
3238     return;
3239   }
3240   Object *ob = iter_data->object;
3241   ParticleSystem *psys = edit->psys;
3242   ParticleCacheKey **cache = edit->pathcache;
3243   ParticleSystemModifierData *psmd = iter_data->psmd;
3244   ParticleData *pa = iter_data->pa ? iter_data->pa + iter : NULL;
3245   PTCacheEditKey *ekey = point->keys;
3246   const int segments = iter_data->segments;
3247   const bool use_weight = iter_data->use_weight;
3248 
3249   float birthtime = 0.0f, dietime = 0.0f;
3250   float hairmat[4][4], rotmat[3][3], prev_tangent[3] = {0.0f, 0.0f, 0.0f};
3251 
3252   ParticleInterpolationData pind;
3253   pind.keyed = 0;
3254   pind.cache = NULL;
3255   pind.epoint = point;
3256   pind.bspline = psys ? (psys->part->flag & PART_HAIR_BSPLINE) : 0;
3257   pind.mesh = NULL;
3258 
3259   /* should init_particle_interpolation set this ? */
3260   if (use_weight) {
3261     pind.hkey[0] = NULL;
3262     /* pa != NULL since the weight brush is only available for hair */
3263     pind.hkey[0] = pa->hair;
3264     pind.hkey[1] = pa->hair + 1;
3265   }
3266 
3267   memset(cache[iter], 0, sizeof(*cache[iter]) * (segments + 1));
3268 
3269   cache[iter]->segments = segments;
3270 
3271   /*--get the first data points--*/
3272   init_particle_interpolation(ob, psys, pa, &pind);
3273 
3274   if (psys) {
3275     psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, pa, hairmat);
3276     copy_v3_v3(rotmat[0], hairmat[2]);
3277     copy_v3_v3(rotmat[1], hairmat[1]);
3278     copy_v3_v3(rotmat[2], hairmat[0]);
3279   }
3280 
3281   birthtime = pind.birthtime;
3282   dietime = pind.dietime;
3283 
3284   if (birthtime >= dietime) {
3285     cache[iter]->segments = -1;
3286     return;
3287   }
3288 
3289   /*--interpolate actual path from data points--*/
3290   ParticleCacheKey *ca;
3291   int k;
3292   float t, time = 0.0f, keytime = 0.0f;
3293   for (k = 0, ca = cache[iter]; k <= segments; k++, ca++) {
3294     time = (float)k / (float)segments;
3295     t = birthtime + time * (dietime - birthtime);
3296     ParticleKey result;
3297     result.time = -t;
3298     do_particle_interpolation(psys, iter, pa, t, &pind, &result);
3299     copy_v3_v3(ca->co, result.co);
3300 
3301     /* non-hair points are already in global space */
3302     if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
3303       mul_m4_v3(hairmat, ca->co);
3304 
3305       if (k) {
3306         cache_key_incremental_rotation(ca, ca - 1, ca - 2, prev_tangent, k);
3307 
3308         if (k == segments) {
3309           copy_qt_qt(ca->rot, (ca - 1)->rot);
3310         }
3311 
3312         /* set velocity */
3313         sub_v3_v3v3(ca->vel, ca->co, (ca - 1)->co);
3314 
3315         if (k == 1) {
3316           copy_v3_v3((ca - 1)->vel, ca->vel);
3317         }
3318       }
3319     }
3320     else {
3321       ca->vel[0] = ca->vel[1] = 0.0f;
3322       ca->vel[2] = 1.0f;
3323     }
3324 
3325     /* selection coloring in edit mode */
3326     if (use_weight) {
3327       if (k == 0) {
3328         BKE_defvert_weight_to_rgb(ca->col, pind.hkey[1]->weight);
3329       }
3330       else {
3331         /* warning: copied from 'do_particle_interpolation' (without 'mvert' array stepping) */
3332         float real_t;
3333         if (result.time < 0.0f) {
3334           real_t = -result.time;
3335         }
3336         else {
3337           real_t = pind.hkey[0]->time +
3338                    t * (pind.hkey[0][pa->totkey - 1].time - pind.hkey[0]->time);
3339         }
3340 
3341         while (pind.hkey[1]->time < real_t) {
3342           pind.hkey[1]++;
3343         }
3344         pind.hkey[0] = pind.hkey[1] - 1;
3345         /* end copy */
3346 
3347         float w1[3], w2[3];
3348         keytime = (t - (*pind.ekey[0]->time)) / ((*pind.ekey[1]->time) - (*pind.ekey[0]->time));
3349 
3350         BKE_defvert_weight_to_rgb(w1, pind.hkey[0]->weight);
3351         BKE_defvert_weight_to_rgb(w2, pind.hkey[1]->weight);
3352 
3353         interp_v3_v3v3(ca->col, w1, w2, keytime);
3354       }
3355     }
3356     else {
3357       /* HACK(fclem): Instead of setting the color we pass the select state in the red channel.
3358        * This is then picked up in DRW and the gpu shader will do the color interpolation. */
3359       if ((ekey + (pind.ekey[0] - point->keys))->flag & PEK_SELECT) {
3360         if ((ekey + (pind.ekey[1] - point->keys))->flag & PEK_SELECT) {
3361           ca->col[0] = 1.0f;
3362         }
3363         else {
3364           keytime = (t - (*pind.ekey[0]->time)) / ((*pind.ekey[1]->time) - (*pind.ekey[0]->time));
3365           ca->col[0] = 1.0f - keytime;
3366         }
3367       }
3368       else {
3369         if ((ekey + (pind.ekey[1] - point->keys))->flag & PEK_SELECT) {
3370           keytime = (t - (*pind.ekey[0]->time)) / ((*pind.ekey[1]->time) - (*pind.ekey[0]->time));
3371           ca->col[0] = keytime;
3372         }
3373         else {
3374           ca->col[0] = 0.0f;
3375         }
3376       }
3377     }
3378 
3379     ca->time = t;
3380   }
3381   if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
3382     /* First rotation is based on emitting face orientation.
3383      * This is way better than having flipping rotations resulting
3384      * from using a global axis as a rotation pole (vec_to_quat()).
3385      * It's not an ideal solution though since it disregards the
3386      * initial tangent, but taking that in to account will allow
3387      * the possibility of flipping again. -jahka
3388      */
3389     mat3_to_quat_is_ok(cache[iter]->rot, rotmat);
3390   }
3391 }
3392 
psys_cache_edit_paths(Depsgraph * depsgraph,Scene * scene,Object * ob,PTCacheEdit * edit,float cfra,const bool use_render_params)3393 void psys_cache_edit_paths(Depsgraph *depsgraph,
3394                            Scene *scene,
3395                            Object *ob,
3396                            PTCacheEdit *edit,
3397                            float cfra,
3398                            const bool use_render_params)
3399 {
3400   ParticleCacheKey **cache = edit->pathcache;
3401   ParticleEditSettings *pset = &scene->toolsettings->particle;
3402 
3403   ParticleSystem *psys = edit->psys;
3404 
3405   ParticleData *pa = psys ? psys->particles : NULL;
3406 
3407   int segments = 1 << pset->draw_step;
3408   int totpart = edit->totpoint, recalc_set = 0;
3409 
3410   if (edit->psmd_eval == NULL) {
3411     return;
3412   }
3413 
3414   segments = MAX2(segments, 4);
3415 
3416   if (!cache || edit->totpoint != edit->totcached) {
3417     /* Clear out old and create new empty path cache. */
3418     psys_free_path_cache(edit->psys, edit);
3419     cache = edit->pathcache = psys_alloc_path_cache_buffers(
3420         &edit->pathcachebufs, totpart, segments + 1);
3421     /* Set flag for update (child particles check this too). */
3422     int i;
3423     PTCacheEditPoint *point;
3424     for (i = 0, point = edit->points; i < totpart; i++, point++) {
3425       point->flag |= PEP_EDIT_RECALC;
3426     }
3427     recalc_set = 1;
3428   }
3429 
3430   const bool use_weight = (pset->brushtype == PE_BRUSH_WEIGHT) && (psys != NULL) &&
3431                           (psys->particles != NULL);
3432 
3433   CacheEditrPathsIterData iter_data;
3434   iter_data.object = ob;
3435   iter_data.edit = edit;
3436   iter_data.psmd = edit->psmd_eval;
3437   iter_data.pa = pa;
3438   iter_data.segments = segments;
3439   iter_data.use_weight = use_weight;
3440 
3441   TaskParallelSettings settings;
3442   BLI_parallel_range_settings_defaults(&settings);
3443   BLI_task_parallel_range(0, edit->totpoint, &iter_data, psys_cache_edit_paths_iter, &settings);
3444 
3445   edit->totcached = totpart;
3446 
3447   if (psys) {
3448     ParticleSimulationData sim = {0};
3449     sim.depsgraph = depsgraph;
3450     sim.scene = scene;
3451     sim.ob = ob;
3452     sim.psys = psys;
3453     sim.psmd = edit->psmd_eval;
3454 
3455     psys_cache_child_paths(&sim, cfra, true, use_render_params);
3456   }
3457 
3458   /* clear recalc flag if set here */
3459   if (recalc_set) {
3460     PTCacheEditPoint *point;
3461     int i;
3462     for (i = 0, point = edit->points; i < totpart; i++, point++) {
3463       point->flag &= ~PEP_EDIT_RECALC;
3464     }
3465   }
3466 }
3467 /************************************************/
3468 /*          Particle Key handling               */
3469 /************************************************/
copy_particle_key(ParticleKey * to,ParticleKey * from,int time)3470 void copy_particle_key(ParticleKey *to, ParticleKey *from, int time)
3471 {
3472   if (time) {
3473     memcpy(to, from, sizeof(ParticleKey));
3474   }
3475   else {
3476     float to_time = to->time;
3477     memcpy(to, from, sizeof(ParticleKey));
3478     to->time = to_time;
3479   }
3480 }
psys_get_from_key(ParticleKey * key,float loc[3],float vel[3],float rot[4],float * time)3481 void psys_get_from_key(ParticleKey *key, float loc[3], float vel[3], float rot[4], float *time)
3482 {
3483   if (loc) {
3484     copy_v3_v3(loc, key->co);
3485   }
3486   if (vel) {
3487     copy_v3_v3(vel, key->vel);
3488   }
3489   if (rot) {
3490     copy_qt_qt(rot, key->rot);
3491   }
3492   if (time) {
3493     *time = key->time;
3494   }
3495 }
3496 
triatomat(float * v1,float * v2,float * v3,float (* uv)[2],float mat[4][4])3497 static void triatomat(float *v1, float *v2, float *v3, float (*uv)[2], float mat[4][4])
3498 {
3499   float det, w1, w2, d1[2], d2[2];
3500 
3501   memset(mat, 0, sizeof(float[4][4]));
3502   mat[3][3] = 1.0f;
3503 
3504   /* first axis is the normal */
3505   normal_tri_v3(mat[2], v1, v2, v3);
3506 
3507   /* second axis along (1, 0) in uv space */
3508   if (uv) {
3509     d1[0] = uv[1][0] - uv[0][0];
3510     d1[1] = uv[1][1] - uv[0][1];
3511     d2[0] = uv[2][0] - uv[0][0];
3512     d2[1] = uv[2][1] - uv[0][1];
3513 
3514     det = d2[0] * d1[1] - d2[1] * d1[0];
3515 
3516     if (det != 0.0f) {
3517       det = 1.0f / det;
3518       w1 = -d2[1] * det;
3519       w2 = d1[1] * det;
3520 
3521       mat[1][0] = w1 * (v2[0] - v1[0]) + w2 * (v3[0] - v1[0]);
3522       mat[1][1] = w1 * (v2[1] - v1[1]) + w2 * (v3[1] - v1[1]);
3523       mat[1][2] = w1 * (v2[2] - v1[2]) + w2 * (v3[2] - v1[2]);
3524       normalize_v3(mat[1]);
3525     }
3526     else {
3527       mat[1][0] = mat[1][1] = mat[1][2] = 0.0f;
3528     }
3529   }
3530   else {
3531     sub_v3_v3v3(mat[1], v2, v1);
3532     normalize_v3(mat[1]);
3533   }
3534 
3535   /* third as a cross product */
3536   cross_v3_v3v3(mat[0], mat[1], mat[2]);
3537 }
3538 
psys_face_mat(Object * ob,Mesh * mesh,ParticleData * pa,float mat[4][4],int orco)3539 static void psys_face_mat(Object *ob, Mesh *mesh, ParticleData *pa, float mat[4][4], int orco)
3540 {
3541   float v[3][3];
3542   MFace *mface;
3543   OrigSpaceFace *osface;
3544   float(*orcodata)[3];
3545 
3546   int i = (ELEM(pa->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND)) ? pa->num : pa->num_dmcache;
3547   if (i == -1 || i >= mesh->totface) {
3548     unit_m4(mat);
3549     return;
3550   }
3551 
3552   mface = &mesh->mface[i];
3553   osface = CustomData_get(&mesh->fdata, i, CD_ORIGSPACE);
3554 
3555   if (orco && (orcodata = CustomData_get_layer(&mesh->vdata, CD_ORCO))) {
3556     copy_v3_v3(v[0], orcodata[mface->v1]);
3557     copy_v3_v3(v[1], orcodata[mface->v2]);
3558     copy_v3_v3(v[2], orcodata[mface->v3]);
3559 
3560     /* ugly hack to use non-transformed orcos, since only those
3561      * give symmetric results for mirroring in particle mode */
3562     if (CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX)) {
3563       BKE_mesh_orco_verts_transform(ob->data, v, 3, 1);
3564     }
3565   }
3566   else {
3567     copy_v3_v3(v[0], mesh->mvert[mface->v1].co);
3568     copy_v3_v3(v[1], mesh->mvert[mface->v2].co);
3569     copy_v3_v3(v[2], mesh->mvert[mface->v3].co);
3570   }
3571 
3572   triatomat(v[0], v[1], v[2], (osface) ? osface->uv : NULL, mat);
3573 }
3574 
psys_mat_hair_to_object(Object * UNUSED (ob),Mesh * mesh,short from,ParticleData * pa,float hairmat[4][4])3575 void psys_mat_hair_to_object(
3576     Object *UNUSED(ob), Mesh *mesh, short from, ParticleData *pa, float hairmat[4][4])
3577 {
3578   float vec[3];
3579 
3580   /* can happen when called from a different object's modifier */
3581   if (!mesh) {
3582     unit_m4(hairmat);
3583     return;
3584   }
3585 
3586   psys_face_mat(0, mesh, pa, hairmat, 0);
3587   psys_particle_on_dm(mesh, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, 0);
3588   copy_v3_v3(hairmat[3], vec);
3589 }
3590 
psys_mat_hair_to_orco(Object * ob,Mesh * mesh,short from,ParticleData * pa,float hairmat[4][4])3591 void psys_mat_hair_to_orco(
3592     Object *ob, Mesh *mesh, short from, ParticleData *pa, float hairmat[4][4])
3593 {
3594   float vec[3], orco[3];
3595 
3596   psys_face_mat(ob, mesh, pa, hairmat, 1);
3597   psys_particle_on_dm(
3598       mesh, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, orco);
3599 
3600   /* see psys_face_mat for why this function is called */
3601   if (CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX)) {
3602     BKE_mesh_orco_verts_transform(ob->data, &orco, 1, 1);
3603   }
3604   copy_v3_v3(hairmat[3], orco);
3605 }
3606 
psys_vec_rot_to_face(Mesh * mesh,ParticleData * pa,float vec[3])3607 void psys_vec_rot_to_face(Mesh *mesh, ParticleData *pa, float vec[3])
3608 {
3609   float mat[4][4];
3610 
3611   psys_face_mat(0, mesh, pa, mat, 0);
3612   transpose_m4(mat); /* cheap inverse for rotation matrix */
3613   mul_mat3_m4_v3(mat, vec);
3614 }
3615 
psys_mat_hair_to_global(Object * ob,Mesh * mesh,short from,ParticleData * pa,float hairmat[4][4])3616 void psys_mat_hair_to_global(
3617     Object *ob, Mesh *mesh, short from, ParticleData *pa, float hairmat[4][4])
3618 {
3619   float facemat[4][4];
3620 
3621   psys_mat_hair_to_object(ob, mesh, from, pa, facemat);
3622 
3623   mul_m4_m4m4(hairmat, ob->obmat, facemat);
3624 }
3625 
3626 /************************************************/
3627 /*          ParticleSettings handling           */
3628 /************************************************/
object_add_or_copy_particle_system(Main * bmain,Scene * scene,Object * ob,const char * name,const ParticleSystem * psys_orig)3629 static ModifierData *object_add_or_copy_particle_system(
3630     Main *bmain, Scene *scene, Object *ob, const char *name, const ParticleSystem *psys_orig)
3631 {
3632   ParticleSystem *psys;
3633   ModifierData *md;
3634   ParticleSystemModifierData *psmd;
3635 
3636   if (!ob || ob->type != OB_MESH) {
3637     return NULL;
3638   }
3639 
3640   if (name == NULL) {
3641     name = (psys_orig != NULL) ? psys_orig->name : DATA_("ParticleSettings");
3642   }
3643 
3644   psys = ob->particlesystem.first;
3645   for (; psys; psys = psys->next) {
3646     psys->flag &= ~PSYS_CURRENT;
3647   }
3648 
3649   psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");
3650   psys->pointcache = BKE_ptcache_add(&psys->ptcaches);
3651   BLI_addtail(&ob->particlesystem, psys);
3652   psys_unique_name(ob, psys, name);
3653 
3654   if (psys_orig != NULL) {
3655     psys->part = psys_orig->part;
3656     id_us_plus(&psys->part->id);
3657   }
3658   else {
3659     psys->part = BKE_particlesettings_add(bmain, psys->name);
3660   }
3661   md = BKE_modifier_new(eModifierType_ParticleSystem);
3662   BLI_strncpy(md->name, psys->name, sizeof(md->name));
3663   BKE_modifier_unique_name(&ob->modifiers, md);
3664 
3665   psmd = (ParticleSystemModifierData *)md;
3666   psmd->psys = psys;
3667   BLI_addtail(&ob->modifiers, md);
3668 
3669   psys->totpart = 0;
3670   psys->flag = PSYS_CURRENT;
3671   if (scene != NULL) {
3672     psys->cfra = BKE_scene_frame_to_ctime(scene, CFRA + 1);
3673   }
3674 
3675   DEG_relations_tag_update(bmain);
3676   DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
3677 
3678   return md;
3679 }
3680 
object_add_particle_system(Main * bmain,Scene * scene,Object * ob,const char * name)3681 ModifierData *object_add_particle_system(Main *bmain, Scene *scene, Object *ob, const char *name)
3682 {
3683   return object_add_or_copy_particle_system(bmain, scene, ob, name, NULL);
3684 }
3685 
object_copy_particle_system(Main * bmain,Scene * scene,Object * ob,const ParticleSystem * psys_orig)3686 ModifierData *object_copy_particle_system(Main *bmain,
3687                                           Scene *scene,
3688                                           Object *ob,
3689                                           const ParticleSystem *psys_orig)
3690 {
3691   return object_add_or_copy_particle_system(bmain, scene, ob, NULL, psys_orig);
3692 }
3693 
object_remove_particle_system(Main * bmain,Scene * UNUSED (scene),Object * ob)3694 void object_remove_particle_system(Main *bmain, Scene *UNUSED(scene), Object *ob)
3695 {
3696   ParticleSystem *psys = psys_get_current(ob);
3697   ParticleSystemModifierData *psmd;
3698   ModifierData *md;
3699 
3700   if (!psys) {
3701     return;
3702   }
3703 
3704   /* Clear particle system in fluid modifier. */
3705   if ((md = BKE_modifiers_findby_type(ob, eModifierType_Fluid))) {
3706     FluidModifierData *fmd = (FluidModifierData *)md;
3707 
3708     /* Clear particle system pointer in flow settings. */
3709     if ((fmd->type == MOD_FLUID_TYPE_FLOW) && fmd->flow && fmd->flow->psys) {
3710       if (fmd->flow->psys == psys) {
3711         fmd->flow->psys = NULL;
3712       }
3713     }
3714     /* Clear particle flag in domain settings when removing particle system manually. */
3715     if (fmd->type == MOD_FLUID_TYPE_DOMAIN) {
3716       if (psys->part->type == PART_FLUID_FLIP) {
3717         fmd->domain->particle_type &= ~FLUID_DOMAIN_PARTICLE_FLIP;
3718       }
3719       if (psys->part->type == PART_FLUID_SPRAY || psys->part->type == PART_FLUID_SPRAYFOAM ||
3720           psys->part->type == PART_FLUID_SPRAYBUBBLE ||
3721           psys->part->type == PART_FLUID_SPRAYFOAMBUBBLE) {
3722         fmd->domain->particle_type &= ~FLUID_DOMAIN_PARTICLE_SPRAY;
3723       }
3724       if (psys->part->type == PART_FLUID_FOAM || psys->part->type == PART_FLUID_SPRAYFOAM ||
3725           psys->part->type == PART_FLUID_FOAMBUBBLE ||
3726           psys->part->type == PART_FLUID_SPRAYFOAMBUBBLE) {
3727         fmd->domain->particle_type &= ~FLUID_DOMAIN_PARTICLE_FOAM;
3728       }
3729       if (psys->part->type == PART_FLUID_BUBBLE || psys->part->type == PART_FLUID_FOAMBUBBLE ||
3730           psys->part->type == PART_FLUID_SPRAYBUBBLE ||
3731           psys->part->type == PART_FLUID_SPRAYFOAMBUBBLE) {
3732         fmd->domain->particle_type &= ~FLUID_DOMAIN_PARTICLE_BUBBLE;
3733       }
3734       if (psys->part->type == PART_FLUID_TRACER) {
3735         fmd->domain->particle_type &= ~FLUID_DOMAIN_PARTICLE_TRACER;
3736       }
3737 
3738       /* Disable combined export if combined particle system was deleted. */
3739       if (psys->part->type == PART_FLUID_SPRAYFOAM || psys->part->type == PART_FLUID_SPRAYBUBBLE ||
3740           psys->part->type == PART_FLUID_FOAMBUBBLE ||
3741           psys->part->type == PART_FLUID_SPRAYFOAMBUBBLE) {
3742         fmd->domain->sndparticle_combined_export = SNDPARTICLE_COMBINED_EXPORT_OFF;
3743       }
3744     }
3745   }
3746 
3747   if ((md = BKE_modifiers_findby_type(ob, eModifierType_DynamicPaint))) {
3748     DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
3749     if (pmd->brush && pmd->brush->psys) {
3750       if (pmd->brush->psys == psys) {
3751         pmd->brush->psys = NULL;
3752       }
3753     }
3754   }
3755 
3756   /* Clear modifier, skip empty ones. */
3757   psmd = psys_get_modifier(ob, psys);
3758   if (psmd) {
3759     BLI_remlink(&ob->modifiers, psmd);
3760     BKE_modifier_free((ModifierData *)psmd);
3761   }
3762 
3763   /* Clear particle system. */
3764   BLI_remlink(&ob->particlesystem, psys);
3765   if (psys->part) {
3766     id_us_min(&psys->part->id);
3767   }
3768   psys_free(ob, psys);
3769 
3770   if (ob->particlesystem.first) {
3771     ((ParticleSystem *)ob->particlesystem.first)->flag |= PSYS_CURRENT;
3772   }
3773   else {
3774     ob->mode &= ~OB_MODE_PARTICLE_EDIT;
3775   }
3776 
3777   DEG_relations_tag_update(bmain);
3778   DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
3779 
3780   /* Flush object mode. */
3781   DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
3782 }
3783 
BKE_particlesettings_add(Main * bmain,const char * name)3784 ParticleSettings *BKE_particlesettings_add(Main *bmain, const char *name)
3785 {
3786   ParticleSettings *part;
3787 
3788   part = BKE_id_new(bmain, ID_PA, name);
3789 
3790   return part;
3791 }
3792 
BKE_particlesettings_clump_curve_init(ParticleSettings * part)3793 void BKE_particlesettings_clump_curve_init(ParticleSettings *part)
3794 {
3795   CurveMapping *cumap = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
3796 
3797   cumap->cm[0].curve[0].x = 0.0f;
3798   cumap->cm[0].curve[0].y = 1.0f;
3799   cumap->cm[0].curve[1].x = 1.0f;
3800   cumap->cm[0].curve[1].y = 1.0f;
3801 
3802   BKE_curvemapping_init(cumap);
3803 
3804   part->clumpcurve = cumap;
3805 }
3806 
BKE_particlesettings_rough_curve_init(ParticleSettings * part)3807 void BKE_particlesettings_rough_curve_init(ParticleSettings *part)
3808 {
3809   CurveMapping *cumap = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
3810 
3811   cumap->cm[0].curve[0].x = 0.0f;
3812   cumap->cm[0].curve[0].y = 1.0f;
3813   cumap->cm[0].curve[1].x = 1.0f;
3814   cumap->cm[0].curve[1].y = 1.0f;
3815 
3816   BKE_curvemapping_init(cumap);
3817 
3818   part->roughcurve = cumap;
3819 }
3820 
BKE_particlesettings_twist_curve_init(ParticleSettings * part)3821 void BKE_particlesettings_twist_curve_init(ParticleSettings *part)
3822 {
3823   CurveMapping *cumap = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
3824 
3825   cumap->cm[0].curve[0].x = 0.0f;
3826   cumap->cm[0].curve[0].y = 1.0f;
3827   cumap->cm[0].curve[1].x = 1.0f;
3828   cumap->cm[0].curve[1].y = 1.0f;
3829 
3830   BKE_curvemapping_init(cumap);
3831 
3832   part->twistcurve = cumap;
3833 }
3834 
3835 /************************************************/
3836 /*          Textures                            */
3837 /************************************************/
3838 
get_particle_uv(Mesh * mesh,ParticleData * pa,int index,const float fuv[4],char * name,float * texco,bool from_vert)3839 static int get_particle_uv(Mesh *mesh,
3840                            ParticleData *pa,
3841                            int index,
3842                            const float fuv[4],
3843                            char *name,
3844                            float *texco,
3845                            bool from_vert)
3846 {
3847   MFace *mf;
3848   MTFace *tf;
3849   int i;
3850 
3851   tf = CustomData_get_layer_named(&mesh->fdata, CD_MTFACE, name);
3852 
3853   if (tf == NULL) {
3854     tf = mesh->mtface;
3855   }
3856 
3857   if (tf == NULL) {
3858     return 0;
3859   }
3860 
3861   if (pa) {
3862     i = ELEM(pa->num_dmcache, DMCACHE_NOTFOUND, DMCACHE_ISCHILD) ? pa->num : pa->num_dmcache;
3863     if ((!from_vert && i >= mesh->totface) || (from_vert && i >= mesh->totvert)) {
3864       i = -1;
3865     }
3866   }
3867   else {
3868     i = index;
3869   }
3870 
3871   if (i == -1) {
3872     texco[0] = 0.0f;
3873     texco[1] = 0.0f;
3874     texco[2] = 0.0f;
3875   }
3876   else {
3877     if (from_vert) {
3878       mf = mesh->mface;
3879 
3880       /* This finds the first face to contain the emitting vertex,
3881        * this is not ideal, but is mostly fine as UV seams generally
3882        * map to equal-colored parts of a texture */
3883       for (int j = 0; j < mesh->totface; j++, mf++) {
3884         if (ELEM(i, mf->v1, mf->v2, mf->v3, mf->v4)) {
3885           i = j;
3886           break;
3887         }
3888       }
3889     }
3890     else {
3891       mf = &mesh->mface[i];
3892     }
3893 
3894     psys_interpolate_uvs(&tf[i], mf->v4, fuv, texco);
3895 
3896     texco[0] = texco[0] * 2.0f - 1.0f;
3897     texco[1] = texco[1] * 2.0f - 1.0f;
3898     texco[2] = 0.0f;
3899   }
3900 
3901   return 1;
3902 }
3903 
3904 #define SET_PARTICLE_TEXTURE(type, pvalue, texfac) \
3905   if ((event & mtex->mapto) & type) { \
3906     pvalue = texture_value_blend(def, pvalue, value, texfac, blend); \
3907   } \
3908   (void)0
3909 
3910 #define CLAMP_PARTICLE_TEXTURE_POS(type, pvalue) \
3911   if (event & type) { \
3912     CLAMP(pvalue, 0.0f, 1.0f); \
3913   } \
3914   (void)0
3915 
3916 #define CLAMP_WARP_PARTICLE_TEXTURE_POS(type, pvalue) \
3917   if (event & type) { \
3918     if (pvalue < 0.0f) { \
3919       pvalue = 1.0f + pvalue; \
3920     } \
3921     CLAMP(pvalue, 0.0f, 1.0f); \
3922   } \
3923   (void)0
3924 
3925 #define CLAMP_PARTICLE_TEXTURE_POSNEG(type, pvalue) \
3926   if (event & type) { \
3927     CLAMP(pvalue, -1.0f, 1.0f); \
3928   } \
3929   (void)0
3930 
get_cpa_texture(Mesh * mesh,ParticleSystem * psys,ParticleSettings * part,ParticleData * par,int child_index,int face_index,const float fw[4],float * orco,ParticleTexture * ptex,int event,float cfra)3931 static void get_cpa_texture(Mesh *mesh,
3932                             ParticleSystem *psys,
3933                             ParticleSettings *part,
3934                             ParticleData *par,
3935                             int child_index,
3936                             int face_index,
3937                             const float fw[4],
3938                             float *orco,
3939                             ParticleTexture *ptex,
3940                             int event,
3941                             float cfra)
3942 {
3943   MTex *mtex, **mtexp = part->mtex;
3944   int m;
3945   float value, rgba[4], texvec[3];
3946 
3947   ptex->ivel = ptex->life = ptex->exist = ptex->size = ptex->damp = ptex->gravity = ptex->field =
3948       ptex->time = ptex->clump = ptex->kink_freq = ptex->kink_amp = ptex->effector = ptex->rough1 =
3949           ptex->rough2 = ptex->roughe = 1.0f;
3950   ptex->twist = 1.0f;
3951 
3952   ptex->length = 1.0f - part->randlength * psys_frand(psys, child_index + 26);
3953   ptex->length *= part->clength_thres < psys_frand(psys, child_index + 27) ? part->clength : 1.0f;
3954 
3955   for (m = 0; m < MAX_MTEX; m++, mtexp++) {
3956     mtex = *mtexp;
3957     if (mtex && mtex->tex && mtex->mapto) {
3958       float def = mtex->def_var;
3959       short blend = mtex->blendtype;
3960       short texco = mtex->texco;
3961 
3962       if (ELEM(texco, TEXCO_UV, TEXCO_ORCO) &&
3963           (ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME) == 0 ||
3964            part->distr == PART_DISTR_GRID)) {
3965         texco = TEXCO_GLOB;
3966       }
3967 
3968       switch (texco) {
3969         case TEXCO_GLOB:
3970           copy_v3_v3(texvec, par->state.co);
3971           break;
3972         case TEXCO_OBJECT:
3973           copy_v3_v3(texvec, par->state.co);
3974           if (mtex->object) {
3975             mul_m4_v3(mtex->object->imat, texvec);
3976           }
3977           break;
3978         case TEXCO_UV:
3979           if (fw && get_particle_uv(mesh,
3980                                     NULL,
3981                                     face_index,
3982                                     fw,
3983                                     mtex->uvname,
3984                                     texvec,
3985                                     (part->from == PART_FROM_VERT))) {
3986             break;
3987           }
3988           /* no break, failed to get uv's, so let's try orco's */
3989           ATTR_FALLTHROUGH;
3990         case TEXCO_ORCO:
3991           copy_v3_v3(texvec, orco);
3992           break;
3993         case TEXCO_PARTICLE:
3994           /* texture coordinates in range [-1, 1] */
3995           texvec[0] = 2.f * (cfra - par->time) / (par->dietime - par->time) - 1.f;
3996           texvec[1] = 0.f;
3997           texvec[2] = 0.f;
3998           break;
3999       }
4000 
4001       RE_texture_evaluate(mtex, texvec, 0, NULL, false, false, &value, rgba);
4002 
4003       if ((event & mtex->mapto) & PAMAP_ROUGH) {
4004         ptex->rough1 = ptex->rough2 = ptex->roughe = texture_value_blend(
4005             def, ptex->rough1, value, mtex->roughfac, blend);
4006       }
4007 
4008       SET_PARTICLE_TEXTURE(PAMAP_LENGTH, ptex->length, mtex->lengthfac);
4009       SET_PARTICLE_TEXTURE(PAMAP_CLUMP, ptex->clump, mtex->clumpfac);
4010       SET_PARTICLE_TEXTURE(PAMAP_KINK_AMP, ptex->kink_amp, mtex->kinkampfac);
4011       SET_PARTICLE_TEXTURE(PAMAP_KINK_FREQ, ptex->kink_freq, mtex->kinkfac);
4012       SET_PARTICLE_TEXTURE(PAMAP_DENS, ptex->exist, mtex->padensfac);
4013       SET_PARTICLE_TEXTURE(PAMAP_TWIST, ptex->twist, mtex->twistfac);
4014     }
4015   }
4016 
4017   CLAMP_PARTICLE_TEXTURE_POS(PAMAP_LENGTH, ptex->length);
4018   CLAMP_WARP_PARTICLE_TEXTURE_POS(PAMAP_CLUMP, ptex->clump);
4019   CLAMP_WARP_PARTICLE_TEXTURE_POS(PAMAP_KINK_AMP, ptex->kink_amp);
4020   CLAMP_WARP_PARTICLE_TEXTURE_POS(PAMAP_KINK_FREQ, ptex->kink_freq);
4021   CLAMP_WARP_PARTICLE_TEXTURE_POS(PAMAP_ROUGH, ptex->rough1);
4022   CLAMP_WARP_PARTICLE_TEXTURE_POS(PAMAP_DENS, ptex->exist);
4023 }
psys_get_texture(ParticleSimulationData * sim,ParticleData * pa,ParticleTexture * ptex,int event,float cfra)4024 void psys_get_texture(
4025     ParticleSimulationData *sim, ParticleData *pa, ParticleTexture *ptex, int event, float cfra)
4026 {
4027   Object *ob = sim->ob;
4028   Mesh *me = (Mesh *)ob->data;
4029   ParticleSettings *part = sim->psys->part;
4030   MTex **mtexp = part->mtex;
4031   MTex *mtex;
4032   int m;
4033   float value, rgba[4], co[3], texvec[3];
4034   int setvars = 0;
4035 
4036   /* initialize ptex */
4037   ptex->ivel = ptex->life = ptex->exist = ptex->size = ptex->damp = ptex->gravity = ptex->field =
4038       ptex->length = ptex->clump = ptex->kink_freq = ptex->kink_amp = ptex->effector =
4039           ptex->rough1 = ptex->rough2 = ptex->roughe = 1.0f;
4040   ptex->twist = 1.0f;
4041 
4042   ptex->time = (float)(pa - sim->psys->particles) / (float)sim->psys->totpart;
4043 
4044   for (m = 0; m < MAX_MTEX; m++, mtexp++) {
4045     mtex = *mtexp;
4046     if (mtex && mtex->tex && mtex->mapto) {
4047       float def = mtex->def_var;
4048       short blend = mtex->blendtype;
4049       short texco = mtex->texco;
4050 
4051       if (texco == TEXCO_UV && (ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME) == 0 ||
4052                                 part->distr == PART_DISTR_GRID)) {
4053         texco = TEXCO_GLOB;
4054       }
4055 
4056       switch (texco) {
4057         case TEXCO_GLOB:
4058           copy_v3_v3(texvec, pa->state.co);
4059           break;
4060         case TEXCO_OBJECT:
4061           copy_v3_v3(texvec, pa->state.co);
4062           if (mtex->object) {
4063             mul_m4_v3(mtex->object->imat, texvec);
4064           }
4065           break;
4066         case TEXCO_UV:
4067           if (get_particle_uv(sim->psmd->mesh_final,
4068                               pa,
4069                               0,
4070                               pa->fuv,
4071                               mtex->uvname,
4072                               texvec,
4073                               (part->from == PART_FROM_VERT))) {
4074             break;
4075           }
4076           /* no break, failed to get uv's, so let's try orco's */
4077           ATTR_FALLTHROUGH;
4078         case TEXCO_ORCO:
4079           psys_particle_on_emitter(sim->psmd,
4080                                    sim->psys->part->from,
4081                                    pa->num,
4082                                    pa->num_dmcache,
4083                                    pa->fuv,
4084                                    pa->foffset,
4085                                    co,
4086                                    0,
4087                                    0,
4088                                    0,
4089                                    texvec);
4090 
4091           BKE_mesh_texspace_ensure(me);
4092           sub_v3_v3(texvec, me->loc);
4093           if (me->size[0] != 0.0f) {
4094             texvec[0] /= me->size[0];
4095           }
4096           if (me->size[1] != 0.0f) {
4097             texvec[1] /= me->size[1];
4098           }
4099           if (me->size[2] != 0.0f) {
4100             texvec[2] /= me->size[2];
4101           }
4102           break;
4103         case TEXCO_PARTICLE:
4104           /* texture coordinates in range [-1, 1] */
4105           texvec[0] = 2.f * (cfra - pa->time) / (pa->dietime - pa->time) - 1.f;
4106           if (sim->psys->totpart > 0) {
4107             texvec[1] = 2.f * (float)(pa - sim->psys->particles) / (float)sim->psys->totpart - 1.f;
4108           }
4109           else {
4110             texvec[1] = 0.0f;
4111           }
4112           texvec[2] = 0.f;
4113           break;
4114       }
4115 
4116       RE_texture_evaluate(mtex, texvec, 0, NULL, false, false, &value, rgba);
4117 
4118       if ((event & mtex->mapto) & PAMAP_TIME) {
4119         /* the first time has to set the base value for time regardless of blend mode */
4120         if ((setvars & MAP_PA_TIME) == 0) {
4121           int flip = (mtex->timefac < 0.0f);
4122           float timefac = fabsf(mtex->timefac);
4123           ptex->time *= 1.0f - timefac;
4124           ptex->time += timefac * ((flip) ? 1.0f - value : value);
4125           setvars |= MAP_PA_TIME;
4126         }
4127         else {
4128           ptex->time = texture_value_blend(def, ptex->time, value, mtex->timefac, blend);
4129         }
4130       }
4131       SET_PARTICLE_TEXTURE(PAMAP_LIFE, ptex->life, mtex->lifefac);
4132       SET_PARTICLE_TEXTURE(PAMAP_DENS, ptex->exist, mtex->padensfac);
4133       SET_PARTICLE_TEXTURE(PAMAP_SIZE, ptex->size, mtex->sizefac);
4134       SET_PARTICLE_TEXTURE(PAMAP_IVEL, ptex->ivel, mtex->ivelfac);
4135       SET_PARTICLE_TEXTURE(PAMAP_FIELD, ptex->field, mtex->fieldfac);
4136       SET_PARTICLE_TEXTURE(PAMAP_GRAVITY, ptex->gravity, mtex->gravityfac);
4137       SET_PARTICLE_TEXTURE(PAMAP_DAMP, ptex->damp, mtex->dampfac);
4138       SET_PARTICLE_TEXTURE(PAMAP_LENGTH, ptex->length, mtex->lengthfac);
4139       SET_PARTICLE_TEXTURE(PAMAP_TWIST, ptex->twist, mtex->twistfac);
4140     }
4141   }
4142 
4143   CLAMP_WARP_PARTICLE_TEXTURE_POS(PAMAP_TIME, ptex->time);
4144   CLAMP_WARP_PARTICLE_TEXTURE_POS(PAMAP_LIFE, ptex->life);
4145   CLAMP_WARP_PARTICLE_TEXTURE_POS(PAMAP_DENS, ptex->exist);
4146   CLAMP_PARTICLE_TEXTURE_POS(PAMAP_SIZE, ptex->size);
4147   CLAMP_PARTICLE_TEXTURE_POSNEG(PAMAP_IVEL, ptex->ivel);
4148   CLAMP_PARTICLE_TEXTURE_POSNEG(PAMAP_FIELD, ptex->field);
4149   CLAMP_PARTICLE_TEXTURE_POSNEG(PAMAP_GRAVITY, ptex->gravity);
4150   CLAMP_WARP_PARTICLE_TEXTURE_POS(PAMAP_DAMP, ptex->damp);
4151   CLAMP_PARTICLE_TEXTURE_POS(PAMAP_LENGTH, ptex->length);
4152 }
4153 /************************************************/
4154 /*          Particle State                      */
4155 /************************************************/
psys_get_timestep(ParticleSimulationData * sim)4156 float psys_get_timestep(ParticleSimulationData *sim)
4157 {
4158   return 0.04f * sim->psys->part->timetweak;
4159 }
psys_get_child_time(ParticleSystem * psys,ChildParticle * cpa,float cfra,float * birthtime,float * dietime)4160 float psys_get_child_time(
4161     ParticleSystem *psys, ChildParticle *cpa, float cfra, float *birthtime, float *dietime)
4162 {
4163   ParticleSettings *part = psys->part;
4164   float time, life;
4165 
4166   if (part->childtype == PART_CHILD_FACES) {
4167     int w = 0;
4168     time = 0.0;
4169     while (w < 4 && cpa->pa[w] >= 0) {
4170       time += cpa->w[w] * (psys->particles + cpa->pa[w])->time;
4171       w++;
4172     }
4173 
4174     life = part->lifetime * (1.0f - part->randlife * psys_frand(psys, cpa - psys->child + 25));
4175   }
4176   else {
4177     ParticleData *pa = psys->particles + cpa->parent;
4178 
4179     time = pa->time;
4180     life = pa->lifetime;
4181   }
4182 
4183   if (birthtime) {
4184     *birthtime = time;
4185   }
4186   if (dietime) {
4187     *dietime = time + life;
4188   }
4189 
4190   return (cfra - time) / life;
4191 }
psys_get_child_size(ParticleSystem * psys,ChildParticle * cpa,float UNUSED (cfra),float * UNUSED (pa_time))4192 float psys_get_child_size(ParticleSystem *psys,
4193                           ChildParticle *cpa,
4194                           float UNUSED(cfra),
4195                           float *UNUSED(pa_time))
4196 {
4197   ParticleSettings *part = psys->part;
4198   float size; /* time XXX */
4199 
4200   if (part->childtype == PART_CHILD_FACES) {
4201     int w = 0;
4202     size = 0.0;
4203     while (w < 4 && cpa->pa[w] >= 0) {
4204       size += cpa->w[w] * (psys->particles + cpa->pa[w])->size;
4205       w++;
4206     }
4207   }
4208   else {
4209     size = psys->particles[cpa->parent].size;
4210   }
4211 
4212   size *= part->childsize;
4213 
4214   if (part->childrandsize != 0.0f) {
4215     size *= 1.0f - part->childrandsize * psys_frand(psys, cpa - psys->child + 26);
4216   }
4217 
4218   return size;
4219 }
get_child_modifier_parameters(ParticleSettings * part,ParticleThreadContext * ctx,ChildParticle * cpa,short cpa_from,int cpa_num,float * cpa_fuv,float * orco,ParticleTexture * ptex)4220 static void get_child_modifier_parameters(ParticleSettings *part,
4221                                           ParticleThreadContext *ctx,
4222                                           ChildParticle *cpa,
4223                                           short cpa_from,
4224                                           int cpa_num,
4225                                           float *cpa_fuv,
4226                                           float *orco,
4227                                           ParticleTexture *ptex)
4228 {
4229   ParticleSystem *psys = ctx->sim.psys;
4230   int i = cpa - psys->child;
4231 
4232   get_cpa_texture(ctx->mesh,
4233                   psys,
4234                   part,
4235                   psys->particles + cpa->pa[0],
4236                   i,
4237                   cpa_num,
4238                   cpa_fuv,
4239                   orco,
4240                   ptex,
4241                   PAMAP_DENS | PAMAP_CHILD,
4242                   psys->cfra);
4243 
4244   if (ptex->exist < psys_frand(psys, i + 24)) {
4245     return;
4246   }
4247 
4248   if (ctx->vg_length) {
4249     ptex->length *= psys_interpolate_value_from_verts(
4250         ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_length);
4251   }
4252   if (ctx->vg_clump) {
4253     ptex->clump *= psys_interpolate_value_from_verts(
4254         ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_clump);
4255   }
4256   if (ctx->vg_kink) {
4257     ptex->kink_freq *= psys_interpolate_value_from_verts(
4258         ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_kink);
4259   }
4260   if (ctx->vg_rough1) {
4261     ptex->rough1 *= psys_interpolate_value_from_verts(
4262         ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_rough1);
4263   }
4264   if (ctx->vg_rough2) {
4265     ptex->rough2 *= psys_interpolate_value_from_verts(
4266         ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_rough2);
4267   }
4268   if (ctx->vg_roughe) {
4269     ptex->roughe *= psys_interpolate_value_from_verts(
4270         ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_roughe);
4271   }
4272   if (ctx->vg_effector) {
4273     ptex->effector *= psys_interpolate_value_from_verts(
4274         ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_effector);
4275   }
4276   if (ctx->vg_twist) {
4277     ptex->twist *= psys_interpolate_value_from_verts(
4278         ctx->mesh, cpa_from, cpa_num, cpa_fuv, ctx->vg_twist);
4279   }
4280 }
4281 /* gets hair (or keyed) particles state at the "path time" specified in state->time */
psys_get_particle_on_path(ParticleSimulationData * sim,int p,ParticleKey * state,const bool vel)4282 void psys_get_particle_on_path(ParticleSimulationData *sim,
4283                                int p,
4284                                ParticleKey *state,
4285                                const bool vel)
4286 {
4287   PARTICLE_PSMD;
4288   ParticleSystem *psys = sim->psys;
4289   ParticleSettings *part = sim->psys->part;
4290   Material *ma = BKE_object_material_get(sim->ob, part->omat);
4291   ParticleData *pa;
4292   ChildParticle *cpa;
4293   ParticleTexture ptex;
4294   ParticleKey *par = 0, keys[4], tstate;
4295   ParticleThreadContext ctx; /* fake thread context for child modifiers */
4296   ParticleInterpolationData pind;
4297 
4298   float t;
4299   float co[3], orco[3];
4300   float hairmat[4][4];
4301   int totpart = psys->totpart;
4302   int totchild = psys->totchild;
4303   short between = 0, edit = 0;
4304 
4305   int keyed = part->phystype & PART_PHYS_KEYED && psys->flag & PSYS_KEYED;
4306   int cached = !keyed && part->type != PART_HAIR;
4307 
4308   float *cpa_fuv;
4309   int cpa_num;
4310   short cpa_from;
4311 
4312   /* initialize keys to zero */
4313   memset(keys, 0, sizeof(ParticleKey[4]));
4314 
4315   t = state->time;
4316   CLAMP(t, 0.0f, 1.0f);
4317 
4318   if (p < totpart) {
4319     /* interpolate pathcache directly if it exist */
4320     if (psys->pathcache) {
4321       ParticleCacheKey result;
4322       interpolate_pathcache(psys->pathcache[p], t, &result);
4323       copy_v3_v3(state->co, result.co);
4324       copy_v3_v3(state->vel, result.vel);
4325       copy_qt_qt(state->rot, result.rot);
4326     }
4327     /* otherwise interpolate with other means */
4328     else {
4329       pa = psys->particles + p;
4330 
4331       pind.keyed = keyed;
4332       pind.cache = cached ? psys->pointcache : NULL;
4333       pind.epoint = NULL;
4334       pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE);
4335       /* pind.dm disabled in editmode means we don't get effectors taken into
4336        * account when subdividing for instance */
4337       pind.mesh = psys_in_edit_mode(sim->depsgraph, psys) ?
4338                       NULL :
4339                       psys->hair_out_mesh; /* XXX Sybren EEK */
4340       init_particle_interpolation(sim->ob, psys, pa, &pind);
4341       do_particle_interpolation(psys, p, pa, t, &pind, state);
4342 
4343       if (pind.mesh) {
4344         mul_m4_v3(sim->ob->obmat, state->co);
4345         mul_mat3_m4_v3(sim->ob->obmat, state->vel);
4346       }
4347       else if (!keyed && !cached && !(psys->flag & PSYS_GLOBAL_HAIR)) {
4348         if ((pa->flag & PARS_REKEY) == 0) {
4349           psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, part->from, pa, hairmat);
4350           mul_m4_v3(hairmat, state->co);
4351           mul_mat3_m4_v3(hairmat, state->vel);
4352 
4353           if (sim->psys->effectors && (part->flag & PART_CHILD_GUIDE) == 0) {
4354             do_guides(
4355                 sim->depsgraph, sim->psys->part, sim->psys->effectors, state, p, state->time);
4356             /* TODO: proper velocity handling */
4357           }
4358 
4359           if (psys->lattice_deform_data && edit == 0) {
4360             BKE_lattice_deform_data_eval_co(
4361                 psys->lattice_deform_data, state->co, psys->lattice_strength);
4362           }
4363         }
4364       }
4365     }
4366   }
4367   else if (totchild) {
4368     // invert_m4_m4(imat, ob->obmat);
4369 
4370     /* interpolate childcache directly if it exists */
4371     if (psys->childcache) {
4372       ParticleCacheKey result;
4373       interpolate_pathcache(psys->childcache[p - totpart], t, &result);
4374       copy_v3_v3(state->co, result.co);
4375       copy_v3_v3(state->vel, result.vel);
4376       copy_qt_qt(state->rot, result.rot);
4377     }
4378     else {
4379       float par_co[3], par_orco[3];
4380 
4381       cpa = psys->child + p - totpart;
4382 
4383       if (state->time < 0.0f) {
4384         t = psys_get_child_time(psys, cpa, -state->time, NULL, NULL);
4385       }
4386 
4387       if (part->childtype == PART_CHILD_FACES) {
4388         /* part->parents could still be 0 so we can't test with totparent */
4389         between = 1;
4390       }
4391       if (between) {
4392         int w = 0;
4393         float foffset;
4394 
4395         /* get parent states */
4396         while (w < 4 && cpa->pa[w] >= 0) {
4397           keys[w].time = state->time;
4398           psys_get_particle_on_path(sim, cpa->pa[w], keys + w, 1);
4399           w++;
4400         }
4401 
4402         /* get the original coordinates (orco) for texture usage */
4403         cpa_num = cpa->num;
4404 
4405         foffset = cpa->foffset;
4406         cpa_fuv = cpa->fuv;
4407         cpa_from = PART_FROM_FACE;
4408 
4409         psys_particle_on_emitter(
4410             psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa->fuv, foffset, co, 0, 0, 0, orco);
4411 
4412         /* We need to save the actual root position of the child for
4413          * positioning it accurately to the surface of the emitter. */
4414         // copy_v3_v3(cpa_1st, co);
4415 
4416         // mul_m4_v3(ob->obmat, cpa_1st);
4417 
4418         pa = psys->particles + cpa->parent;
4419 
4420         psys_particle_on_emitter(psmd,
4421                                  part->from,
4422                                  pa->num,
4423                                  pa->num_dmcache,
4424                                  pa->fuv,
4425                                  pa->foffset,
4426                                  par_co,
4427                                  0,
4428                                  0,
4429                                  0,
4430                                  par_orco);
4431         if (part->type == PART_HAIR) {
4432           psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat);
4433         }
4434         else {
4435           unit_m4(hairmat);
4436         }
4437 
4438         pa = 0;
4439       }
4440       else {
4441         /* get the parent state */
4442         keys->time = state->time;
4443         psys_get_particle_on_path(sim, cpa->parent, keys, 1);
4444 
4445         /* get the original coordinates (orco) for texture usage */
4446         pa = psys->particles + cpa->parent;
4447 
4448         cpa_from = part->from;
4449         cpa_num = pa->num;
4450         cpa_fuv = pa->fuv;
4451 
4452         psys_particle_on_emitter(psmd,
4453                                  part->from,
4454                                  pa->num,
4455                                  pa->num_dmcache,
4456                                  pa->fuv,
4457                                  pa->foffset,
4458                                  par_co,
4459                                  0,
4460                                  0,
4461                                  0,
4462                                  par_orco);
4463         if (part->type == PART_HAIR) {
4464           psys_particle_on_emitter(
4465               psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa_fuv, pa->foffset, co, 0, 0, 0, orco);
4466           psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat);
4467         }
4468         else {
4469           copy_v3_v3(orco, cpa->fuv);
4470           unit_m4(hairmat);
4471         }
4472       }
4473 
4474       /* get different child parameters from textures & vgroups */
4475       memset(&ctx, 0, sizeof(ParticleThreadContext));
4476       ctx.sim = *sim;
4477       ctx.mesh = psmd->mesh_final;
4478       ctx.ma = ma;
4479       /* TODO: assign vertex groups */
4480       get_child_modifier_parameters(part, &ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex);
4481 
4482       if (between) {
4483         int w = 0;
4484 
4485         state->co[0] = state->co[1] = state->co[2] = 0.0f;
4486         state->vel[0] = state->vel[1] = state->vel[2] = 0.0f;
4487 
4488         /* child position is the weighted sum of parent positions */
4489         while (w < 4 && cpa->pa[w] >= 0) {
4490           state->co[0] += cpa->w[w] * keys[w].co[0];
4491           state->co[1] += cpa->w[w] * keys[w].co[1];
4492           state->co[2] += cpa->w[w] * keys[w].co[2];
4493 
4494           state->vel[0] += cpa->w[w] * keys[w].vel[0];
4495           state->vel[1] += cpa->w[w] * keys[w].vel[1];
4496           state->vel[2] += cpa->w[w] * keys[w].vel[2];
4497           w++;
4498         }
4499         /* apply offset for correct positioning */
4500         // add_v3_v3(state->co, cpa_1st);
4501       }
4502       else {
4503         /* offset the child from the parent position */
4504         offset_child(cpa, keys, keys->rot, state, part->childflat, part->childrad);
4505       }
4506 
4507       par = keys;
4508 
4509       if (vel) {
4510         copy_particle_key(&tstate, state, 1);
4511       }
4512 
4513       /* apply different deformations to the child path */
4514       ParticleChildModifierContext modifier_ctx = {NULL};
4515       modifier_ctx.thread_ctx = NULL;
4516       modifier_ctx.sim = sim;
4517       modifier_ctx.ptex = &ptex;
4518       modifier_ctx.cpa = cpa;
4519       modifier_ctx.orco = orco;
4520       modifier_ctx.par_co = par->co;
4521       modifier_ctx.par_vel = par->vel;
4522       modifier_ctx.par_rot = par->rot;
4523       modifier_ctx.par_orco = par_orco;
4524       modifier_ctx.parent_keys = psys->childcache ? psys->childcache[p - totpart] : NULL;
4525       do_child_modifiers(&modifier_ctx, hairmat, state, t);
4526 
4527       /* try to estimate correct velocity */
4528       if (vel) {
4529         ParticleKey tstate_tmp;
4530         float length = len_v3(state->vel);
4531 
4532         if (t >= 0.001f) {
4533           tstate_tmp.time = t - 0.001f;
4534           psys_get_particle_on_path(sim, p, &tstate_tmp, 0);
4535           sub_v3_v3v3(state->vel, state->co, tstate_tmp.co);
4536           normalize_v3(state->vel);
4537         }
4538         else {
4539           tstate_tmp.time = t + 0.001f;
4540           psys_get_particle_on_path(sim, p, &tstate_tmp, 0);
4541           sub_v3_v3v3(state->vel, tstate_tmp.co, state->co);
4542           normalize_v3(state->vel);
4543         }
4544 
4545         mul_v3_fl(state->vel, length);
4546       }
4547     }
4548   }
4549 }
4550 /* gets particle's state at a time, returns 1 if particle exists and can be seen and 0 if not */
psys_get_particle_state(ParticleSimulationData * sim,int p,ParticleKey * state,int always)4551 int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *state, int always)
4552 {
4553   ParticleSystem *psys = sim->psys;
4554   ParticleSettings *part = psys->part;
4555   ParticleData *pa = NULL;
4556   ChildParticle *cpa = NULL;
4557   float cfra;
4558   int totpart = psys->totpart;
4559   float timestep = psys_get_timestep(sim);
4560 
4561   /* negative time means "use current time" */
4562   cfra = state->time > 0 ? state->time : DEG_get_ctime(sim->depsgraph);
4563 
4564   if (p >= totpart) {
4565     if (!psys->totchild) {
4566       return 0;
4567     }
4568 
4569     if (part->childtype == PART_CHILD_FACES) {
4570       if (!(psys->flag & PSYS_KEYED)) {
4571         return 0;
4572       }
4573 
4574       cpa = psys->child + p - totpart;
4575 
4576       state->time = psys_get_child_time(psys, cpa, cfra, NULL, NULL);
4577 
4578       if (!always) {
4579         if ((state->time < 0.0f && !(part->flag & PART_UNBORN)) ||
4580             (state->time > 1.0f && !(part->flag & PART_DIED))) {
4581           return 0;
4582         }
4583       }
4584 
4585       state->time = (cfra - (part->sta + (part->end - part->sta) * psys_frand(psys, p + 23))) /
4586                     (part->lifetime * psys_frand(psys, p + 24));
4587 
4588       psys_get_particle_on_path(sim, p, state, 1);
4589       return 1;
4590     }
4591 
4592     cpa = sim->psys->child + p - totpart;
4593     pa = sim->psys->particles + cpa->parent;
4594   }
4595   else {
4596     pa = sim->psys->particles + p;
4597   }
4598 
4599   if (pa) {
4600     if (!always) {
4601       if ((cfra < pa->time && (part->flag & PART_UNBORN) == 0) ||
4602           (cfra >= pa->dietime && (part->flag & PART_DIED) == 0)) {
4603         return 0;
4604       }
4605     }
4606 
4607     cfra = MIN2(cfra, pa->dietime);
4608   }
4609 
4610   if (sim->psys->flag & PSYS_KEYED) {
4611     state->time = -cfra;
4612     psys_get_particle_on_path(sim, p, state, 1);
4613     return 1;
4614   }
4615 
4616   if (cpa) {
4617     float mat[4][4];
4618     ParticleKey *key1;
4619     float t = (cfra - pa->time) / pa->lifetime;
4620     const float par_orco[3] = {0.0f, 0.0f, 0.0f};
4621 
4622     key1 = &pa->state;
4623     offset_child(cpa, key1, key1->rot, state, part->childflat, part->childrad);
4624 
4625     CLAMP(t, 0.0f, 1.0f);
4626 
4627     unit_m4(mat);
4628     ParticleChildModifierContext modifier_ctx = {NULL};
4629     modifier_ctx.thread_ctx = NULL;
4630     modifier_ctx.sim = sim;
4631     modifier_ctx.ptex = NULL;
4632     modifier_ctx.cpa = cpa;
4633     modifier_ctx.orco = cpa->fuv;
4634     modifier_ctx.par_co = key1->co;
4635     modifier_ctx.par_vel = key1->vel;
4636     modifier_ctx.par_rot = key1->rot;
4637     modifier_ctx.par_orco = par_orco;
4638     modifier_ctx.parent_keys = psys->childcache ? psys->childcache[p - totpart] : NULL;
4639 
4640     do_child_modifiers(&modifier_ctx, mat, state, t);
4641 
4642     if (psys->lattice_deform_data) {
4643       BKE_lattice_deform_data_eval_co(
4644           psys->lattice_deform_data, state->co, psys->lattice_strength);
4645     }
4646   }
4647   else {
4648     if (pa->state.time == cfra || ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED)) {
4649       copy_particle_key(state, &pa->state, 1);
4650     }
4651     else if (pa->prev_state.time == cfra) {
4652       copy_particle_key(state, &pa->prev_state, 1);
4653     }
4654     else {
4655       float dfra, frs_sec = sim->scene->r.frs_sec;
4656       /* let's interpolate to try to be as accurate as possible */
4657       if (pa->state.time + 2.f >= state->time && pa->prev_state.time - 2.f <= state->time) {
4658         if (pa->prev_state.time >= pa->state.time || pa->prev_state.time < 0.f) {
4659           /* prev_state is wrong so let's not use it,
4660            * this can happen at frames 1, 0 or particle birth. */
4661           dfra = state->time - pa->state.time;
4662 
4663           copy_particle_key(state, &pa->state, 1);
4664 
4665           madd_v3_v3v3fl(state->co, state->co, state->vel, dfra / frs_sec);
4666         }
4667         else {
4668           ParticleKey keys[4];
4669           float keytime;
4670 
4671           copy_particle_key(keys + 1, &pa->prev_state, 1);
4672           copy_particle_key(keys + 2, &pa->state, 1);
4673 
4674           dfra = keys[2].time - keys[1].time;
4675 
4676           keytime = (state->time - keys[1].time) / dfra;
4677 
4678           /* convert velocity to timestep size */
4679           mul_v3_fl(keys[1].vel, dfra * timestep);
4680           mul_v3_fl(keys[2].vel, dfra * timestep);
4681 
4682           psys_interpolate_particle(-1, keys, keytime, state, 1);
4683 
4684           /* convert back to real velocity */
4685           mul_v3_fl(state->vel, 1.f / (dfra * timestep));
4686 
4687           interp_v3_v3v3(state->ave, keys[1].ave, keys[2].ave, keytime);
4688           interp_qt_qtqt(state->rot, keys[1].rot, keys[2].rot, keytime);
4689         }
4690       }
4691       else if (pa->state.time + 1.f >= state->time && pa->state.time - 1.f <= state->time) {
4692         /* linear interpolation using only pa->state */
4693 
4694         dfra = state->time - pa->state.time;
4695 
4696         copy_particle_key(state, &pa->state, 1);
4697 
4698         madd_v3_v3v3fl(state->co, state->co, state->vel, dfra / frs_sec);
4699       }
4700       else {
4701         /* Extrapolating over big ranges is not accurate
4702          * so let's just give something close to reasonable back. */
4703         copy_particle_key(state, &pa->state, 0);
4704       }
4705     }
4706 
4707     if (sim->psys->lattice_deform_data) {
4708       BKE_lattice_deform_data_eval_co(
4709           sim->psys->lattice_deform_data, state->co, psys->lattice_strength);
4710     }
4711   }
4712 
4713   return 1;
4714 }
4715 
psys_get_dupli_texture(ParticleSystem * psys,ParticleSettings * part,ParticleSystemModifierData * psmd,ParticleData * pa,ChildParticle * cpa,float uv[2],float orco[3])4716 void psys_get_dupli_texture(ParticleSystem *psys,
4717                             ParticleSettings *part,
4718                             ParticleSystemModifierData *psmd,
4719                             ParticleData *pa,
4720                             ChildParticle *cpa,
4721                             float uv[2],
4722                             float orco[3])
4723 {
4724   MFace *mface;
4725   float loc[3];
4726   int num;
4727 
4728   /* XXX: on checking '(psmd->dm != NULL)'
4729    * This is incorrect but needed for meta-ball evaluation.
4730    * Ideally this would be calculated via the depsgraph, however with meta-balls,
4731    * the entire scenes dupli's are scanned, which also looks into uncalculated data.
4732    *
4733    * For now just include this workaround as an alternative to crashing,
4734    * but longer term meta-balls should behave in a more manageable way, see: T46622. */
4735 
4736   uv[0] = uv[1] = 0.0f;
4737 
4738   /* Grid distribution doesn't support UV or emit from vertex mode */
4739   bool is_grid = (part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT);
4740 
4741   if (cpa) {
4742     if ((part->childtype == PART_CHILD_FACES) && (psmd->mesh_final != NULL)) {
4743       if (!is_grid) {
4744         CustomData *mtf_data = &psmd->mesh_final->fdata;
4745         const int uv_idx = CustomData_get_render_layer(mtf_data, CD_MTFACE);
4746 
4747         if (uv_idx >= 0) {
4748           MTFace *mtface = CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx);
4749           if (mtface != NULL) {
4750             mface = CustomData_get(&psmd->mesh_final->fdata, cpa->num, CD_MFACE);
4751             mtface += cpa->num;
4752             psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, uv);
4753           }
4754         }
4755       }
4756 
4757       psys_particle_on_emitter(psmd,
4758                                PART_FROM_FACE,
4759                                cpa->num,
4760                                DMCACHE_ISCHILD,
4761                                cpa->fuv,
4762                                cpa->foffset,
4763                                loc,
4764                                0,
4765                                0,
4766                                0,
4767                                orco);
4768       return;
4769     }
4770 
4771     pa = psys->particles + cpa->pa[0];
4772   }
4773 
4774   if ((part->from == PART_FROM_FACE) && (psmd->mesh_final != NULL) && !is_grid) {
4775     num = pa->num_dmcache;
4776 
4777     if (num == DMCACHE_NOTFOUND) {
4778       num = pa->num;
4779     }
4780 
4781     if (num >= psmd->mesh_final->totface) {
4782       /* happens when simplify is enabled
4783        * gives invalid coords but would crash otherwise */
4784       num = DMCACHE_NOTFOUND;
4785     }
4786 
4787     if (!ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) {
4788       CustomData *mtf_data = &psmd->mesh_final->fdata;
4789       const int uv_idx = CustomData_get_render_layer(mtf_data, CD_MTFACE);
4790 
4791       if (uv_idx >= 0) {
4792         MTFace *mtface = CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx);
4793         mface = CustomData_get(&psmd->mesh_final->fdata, num, CD_MFACE);
4794         mtface += num;
4795         psys_interpolate_uvs(mtface, mface->v4, pa->fuv, uv);
4796       }
4797     }
4798   }
4799 
4800   psys_particle_on_emitter(
4801       psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, loc, 0, 0, 0, orco);
4802 }
4803 
psys_get_dupli_path_transform(ParticleSimulationData * sim,ParticleData * pa,ChildParticle * cpa,ParticleCacheKey * cache,float mat[4][4],float * scale)4804 void psys_get_dupli_path_transform(ParticleSimulationData *sim,
4805                                    ParticleData *pa,
4806                                    ChildParticle *cpa,
4807                                    ParticleCacheKey *cache,
4808                                    float mat[4][4],
4809                                    float *scale)
4810 {
4811   Object *ob = sim->ob;
4812   ParticleSystem *psys = sim->psys;
4813   ParticleSystemModifierData *psmd = sim->psmd;
4814   float loc[3], nor[3], vec[3], side[3], len;
4815   float xvec[3] = {-1.0, 0.0, 0.0}, nmat[3][3];
4816 
4817   sub_v3_v3v3(vec, (cache + cache->segments)->co, cache->co);
4818   len = normalize_v3(vec);
4819 
4820   if (pa == NULL && psys->part->childflat != PART_CHILD_FACES) {
4821     pa = psys->particles + cpa->pa[0];
4822   }
4823 
4824   if (pa) {
4825     psys_particle_on_emitter(psmd,
4826                              sim->psys->part->from,
4827                              pa->num,
4828                              pa->num_dmcache,
4829                              pa->fuv,
4830                              pa->foffset,
4831                              loc,
4832                              nor,
4833                              0,
4834                              0,
4835                              0);
4836   }
4837   else {
4838     psys_particle_on_emitter(psmd,
4839                              PART_FROM_FACE,
4840                              cpa->num,
4841                              DMCACHE_ISCHILD,
4842                              cpa->fuv,
4843                              cpa->foffset,
4844                              loc,
4845                              nor,
4846                              0,
4847                              0,
4848                              0);
4849   }
4850 
4851   if (psys->part->rotmode == PART_ROT_VEL) {
4852     transpose_m3_m4(nmat, ob->imat);
4853     mul_m3_v3(nmat, nor);
4854     normalize_v3(nor);
4855 
4856     /* make sure that we get a proper side vector */
4857     if (fabsf(dot_v3v3(nor, vec)) > 0.999999f) {
4858       if (fabsf(dot_v3v3(nor, xvec)) > 0.999999f) {
4859         nor[0] = 0.0f;
4860         nor[1] = 1.0f;
4861         nor[2] = 0.0f;
4862       }
4863       else {
4864         nor[0] = 1.0f;
4865         nor[1] = 0.0f;
4866         nor[2] = 0.0f;
4867       }
4868     }
4869     cross_v3_v3v3(side, nor, vec);
4870     normalize_v3(side);
4871 
4872     /* rotate side vector around vec */
4873     if (psys->part->phasefac != 0) {
4874       float q_phase[4];
4875       float phasefac = psys->part->phasefac;
4876       if (psys->part->randphasefac != 0.0f) {
4877         phasefac += psys->part->randphasefac * psys_frand(psys, (pa - psys->particles) + 20);
4878       }
4879       axis_angle_to_quat(q_phase, vec, phasefac * (float)M_PI);
4880 
4881       mul_qt_v3(q_phase, side);
4882     }
4883 
4884     cross_v3_v3v3(nor, vec, side);
4885 
4886     unit_m4(mat);
4887     copy_v3_v3(mat[0], vec);
4888     copy_v3_v3(mat[1], side);
4889     copy_v3_v3(mat[2], nor);
4890   }
4891   else {
4892     quat_to_mat4(mat, pa->state.rot);
4893   }
4894 
4895   *scale = len;
4896 }
4897 
psys_apply_hair_lattice(Depsgraph * depsgraph,Scene * scene,Object * ob,ParticleSystem * psys)4898 void psys_apply_hair_lattice(Depsgraph *depsgraph, Scene *scene, Object *ob, ParticleSystem *psys)
4899 {
4900   ParticleSimulationData sim = {0};
4901   sim.depsgraph = depsgraph;
4902   sim.scene = scene;
4903   sim.ob = ob;
4904   sim.psys = psys;
4905   sim.psmd = psys_get_modifier(ob, psys);
4906 
4907   psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
4908 
4909   if (psys->lattice_deform_data) {
4910     ParticleData *pa = psys->particles;
4911     HairKey *hkey;
4912     int p, h;
4913     float hairmat[4][4], imat[4][4];
4914 
4915     for (p = 0; p < psys->totpart; p++, pa++) {
4916       psys_mat_hair_to_global(sim.ob, sim.psmd->mesh_final, psys->part->from, pa, hairmat);
4917       invert_m4_m4(imat, hairmat);
4918 
4919       hkey = pa->hair;
4920       for (h = 0; h < pa->totkey; h++, hkey++) {
4921         mul_m4_v3(hairmat, hkey->co);
4922         BKE_lattice_deform_data_eval_co(
4923             psys->lattice_deform_data, hkey->co, psys->lattice_strength);
4924         mul_m4_v3(imat, hkey->co);
4925       }
4926     }
4927 
4928     BKE_lattice_deform_data_destroy(psys->lattice_deform_data);
4929     psys->lattice_deform_data = NULL;
4930 
4931     /* protect the applied shape */
4932     psys->flag |= PSYS_EDITED;
4933   }
4934 }
4935 
4936 /* Draw Engine */
4937 void (*BKE_particle_batch_cache_dirty_tag_cb)(ParticleSystem *psys, int mode) = NULL;
4938 void (*BKE_particle_batch_cache_free_cb)(ParticleSystem *psys) = NULL;
4939 
BKE_particle_batch_cache_dirty_tag(ParticleSystem * psys,int mode)4940 void BKE_particle_batch_cache_dirty_tag(ParticleSystem *psys, int mode)
4941 {
4942   if (psys->batch_cache) {
4943     BKE_particle_batch_cache_dirty_tag_cb(psys, mode);
4944   }
4945 }
BKE_particle_batch_cache_free(ParticleSystem * psys)4946 void BKE_particle_batch_cache_free(ParticleSystem *psys)
4947 {
4948   if (psys->batch_cache) {
4949     BKE_particle_batch_cache_free_cb(psys);
4950   }
4951 }
4952