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