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