Blender  V2.93
effect.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
24 #include <stdarg.h>
25 #include <stddef.h>
26 
27 #include <math.h>
28 #include <stdlib.h>
29 
30 #include "MEM_guardedalloc.h"
31 
32 #include "DNA_collection_types.h"
33 #include "DNA_curve_types.h"
34 #include "DNA_listBase.h"
35 #include "DNA_mesh_types.h"
36 #include "DNA_meshdata_types.h"
37 #include "DNA_object_force_types.h"
38 #include "DNA_object_types.h"
39 #include "DNA_particle_types.h"
40 #include "DNA_scene_types.h"
41 #include "DNA_texture_types.h"
42 
43 #include "BLI_blenlib.h"
44 #include "BLI_ghash.h"
45 #include "BLI_math.h"
46 #include "BLI_noise.h"
47 #include "BLI_rand.h"
48 #include "BLI_utildefines.h"
49 
50 #include "PIL_time.h"
51 
52 #include "BKE_anim_path.h" /* needed for where_on_path */
53 #include "BKE_bvhutils.h"
54 #include "BKE_collection.h"
55 #include "BKE_collision.h"
56 #include "BKE_curve.h"
57 #include "BKE_displist.h"
58 #include "BKE_effect.h"
59 #include "BKE_fluid.h"
60 #include "BKE_global.h"
61 #include "BKE_layer.h"
62 #include "BKE_modifier.h"
63 #include "BKE_object.h"
64 #include "BKE_particle.h"
65 #include "BKE_scene.h"
66 
67 #include "DEG_depsgraph.h"
68 #include "DEG_depsgraph_physics.h"
69 #include "DEG_depsgraph_query.h"
70 
71 #include "RE_texture.h"
72 
74 {
75  EffectorWeights *weights = MEM_callocN(sizeof(EffectorWeights), "EffectorWeights");
76  for (int i = 0; i < NUM_PFIELD_TYPES; i++) {
77  weights->weight[i] = 1.0f;
78  }
79 
80  weights->global_gravity = 1.0f;
81 
82  weights->group = collection;
83 
84  return weights;
85 }
87 {
88  PartDeflect *pd;
89 
90  pd = MEM_callocN(sizeof(PartDeflect), "PartDeflect");
91 
92  pd->forcefield = type;
93  pd->pdef_sbdamp = 0.1f;
94  pd->pdef_sbift = 0.2f;
95  pd->pdef_sboft = 0.02f;
96  pd->pdef_cfrict = 5.0f;
97  pd->seed = ((uint)(ceil(PIL_check_seconds_timer())) + 1) % 128;
98  pd->f_strength = 1.0f;
99  pd->f_damp = 1.0f;
100 
101  /* set sensible defaults based on type */
102  switch (type) {
103  case PFIELD_VORTEX:
105  break;
106  case PFIELD_WIND:
108  pd->f_flow = 1.0f; /* realistic wind behavior */
109  pd->f_wind_factor = 1.0f; /* only act perpendicularly to a surface */
110  break;
111  case PFIELD_TEXTURE:
112  pd->f_size = 1.0f;
113  break;
114  case PFIELD_FLUIDFLOW:
115  pd->f_flow = 1.0f;
116  break;
117  }
119 
120  return pd;
121 }
122 
123 /************************ PARTICLES ***************************/
124 
126 {
127  if (pd_src == NULL) {
128  return NULL;
129  }
130  PartDeflect *pd_dst = MEM_dupallocN(pd_src);
131  if (pd_dst->rng != NULL) {
132  pd_dst->rng = BLI_rng_copy(pd_dst->rng);
133  }
134  return pd_dst;
135 }
136 
138 {
139  if (!pd) {
140  return;
141  }
142  if (pd->rng) {
143  BLI_rng_free(pd->rng);
144  }
145  MEM_freeN(pd);
146 }
147 
148 /******************** EFFECTOR RELATIONS ***********************/
149 
151 {
152  float ctime = DEG_get_ctime(depsgraph);
153  uint cfra = (uint)(ctime >= 0 ? ctime : -ctime);
154  if (!eff->pd->rng) {
155  eff->pd->rng = BLI_rng_new(eff->pd->seed + cfra);
156  }
157  else {
158  BLI_rng_srandom(eff->pd->rng, eff->pd->seed + cfra);
159  }
160 
161  if (eff->pd->forcefield == PFIELD_GUIDE && eff->ob->type == OB_CURVE) {
162  Curve *cu = eff->ob->data;
163  if (cu->flag & CU_PATH) {
164  if (eff->ob->runtime.curve_cache == NULL ||
166  BKE_displist_make_curveTypes(depsgraph, eff->scene, eff->ob, false, false);
167  }
168 
171  eff->ob, 0.0, eff->guide_loc, eff->guide_dir, NULL, &eff->guide_radius, NULL);
172  mul_m4_v3(eff->ob->obmat, eff->guide_loc);
173  mul_mat3_m4_v3(eff->ob->obmat, eff->guide_dir);
174  }
175  }
176  }
177  else if (eff->pd->shape == PFIELD_SHAPE_SURFACE) {
179  if (eff->ob->type == OB_CURVE) {
180  eff->flag |= PE_USE_NORMAL_DATA;
181  }
182  }
183  else if (eff->psys) {
184  psys_update_particle_tree(eff->psys, ctime);
185  }
186 }
187 
188 static void add_effector_relation(ListBase *relations,
189  Object *ob,
190  ParticleSystem *psys,
191  PartDeflect *pd)
192 {
193  EffectorRelation *relation = MEM_callocN(sizeof(EffectorRelation), "EffectorRelation");
194  relation->ob = ob;
195  relation->psys = psys;
196  relation->pd = pd;
197 
198  BLI_addtail(relations, relation);
199 }
200 
201 static void add_effector_evaluation(ListBase **effectors,
203  Scene *scene,
204  Object *ob,
205  ParticleSystem *psys,
206  PartDeflect *pd)
207 {
208  if (*effectors == NULL) {
209  *effectors = MEM_callocN(sizeof(ListBase), "effector effectors");
210  }
211 
212  EffectorCache *eff = MEM_callocN(sizeof(EffectorCache), "EffectorCache");
213  eff->depsgraph = depsgraph;
214  eff->scene = scene;
215  eff->ob = ob;
216  eff->psys = psys;
217  eff->pd = pd;
218  eff->frame = -1;
219  BLI_addtail(*effectors, eff);
220 
222 }
223 
224 /* Create list of effector relations in the collection or entire scene.
225  * This is used by the depsgraph to build relations, as well as faster
226  * lookup of effectors during evaluation. */
228  ViewLayer *view_layer,
229  Collection *collection)
230 {
231  Base *base = BKE_collection_or_layer_objects(view_layer, collection);
232  const bool for_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
233  const int base_flag = (for_render) ? BASE_ENABLED_RENDER : BASE_ENABLED_VIEWPORT;
234 
235  ListBase *relations = MEM_callocN(sizeof(ListBase), "effector relations");
236 
237  for (; base; base = base->next) {
238  if (!(base->flag & base_flag)) {
239  continue;
240  }
241 
242  Object *ob = base->object;
243 
244  if (ob->pd && ob->pd->forcefield) {
245  add_effector_relation(relations, ob, NULL, ob->pd);
246  }
247 
249  ParticleSettings *part = psys->part;
250 
251  if (psys_check_enabled(ob, psys, for_render)) {
252  if (part->pd && part->pd->forcefield) {
253  add_effector_relation(relations, ob, psys, part->pd);
254  }
255  if (part->pd2 && part->pd2->forcefield) {
256  add_effector_relation(relations, ob, psys, part->pd2);
257  }
258  }
259  }
260  }
261 
262  return relations;
263 }
264 
266 {
267  if (lb) {
268  BLI_freelistN(lb);
269  MEM_freeN(lb);
270  }
271 }
272 
273 /* Check that the force field isn't disabled via its flags. */
274 static bool is_effector_enabled(PartDeflect *pd, bool use_rotation)
275 {
276  switch (pd->forcefield) {
277  case PFIELD_BOID:
278  case PFIELD_GUIDE:
279  return true;
280 
281  case PFIELD_TEXTURE:
282  return (pd->flag & PFIELD_DO_LOCATION) != 0 && pd->tex != NULL;
283 
284  default:
285  if (use_rotation) {
286  return (pd->flag & (PFIELD_DO_LOCATION | PFIELD_DO_ROTATION)) != 0;
287  }
288  else {
289  return (pd->flag & PFIELD_DO_LOCATION) != 0;
290  }
291  }
292 }
293 
294 /* Check that the force field won't have zero effect due to strength settings. */
296 {
297  if (pd->f_strength != 0.0f) {
298  return true;
299  }
300 
301  if (pd->forcefield == PFIELD_TEXTURE) {
302  return false;
303  }
304 
305  if (pd->f_noise > 0.0f || pd->f_flow != 0.0f) {
306  return true;
307  }
308 
309  switch (pd->forcefield) {
310  case PFIELD_BOID:
311  case PFIELD_GUIDE:
312  return true;
313 
314  case PFIELD_VORTEX:
315  return pd->shape != PFIELD_SHAPE_POINT;
316 
317  case PFIELD_DRAG:
318  return pd->f_damp != 0.0f;
319 
320  default:
321  return false;
322  }
323 }
324 
325 /* Check if the force field will affect its user. */
326 static bool is_effector_relevant(PartDeflect *pd, EffectorWeights *weights, bool use_rotation)
327 {
328  return (weights->weight[pd->forcefield] != 0.0f) && is_effector_enabled(pd, use_rotation) &&
330 }
331 
332 /* Create effective list of effectors from relations built beforehand. */
334  Object *ob_src,
335  ParticleSystem *psys_src,
336  EffectorWeights *weights,
337  bool use_rotation)
338 {
340  ListBase *relations = DEG_get_effector_relations(depsgraph, weights->group);
341  ListBase *effectors = NULL;
342 
343  if (!relations) {
344  return NULL;
345  }
346 
347  LISTBASE_FOREACH (EffectorRelation *, relation, relations) {
348  /* Get evaluated object. */
349  Object *ob = (Object *)DEG_get_evaluated_id(depsgraph, &relation->ob->id);
350 
351  if (relation->psys) {
352  /* Get evaluated particle system. */
354  &ob->particlesystem, relation->psys->name, offsetof(ParticleSystem, name));
355  ParticleSettings *part = psys->part;
356 
357  if (psys == psys_src && (part->flag & PART_SELF_EFFECT) == 0) {
358  continue;
359  }
360 
361  PartDeflect *pd = (relation->pd == relation->psys->part->pd) ? part->pd : part->pd2;
362 
363  if (!is_effector_relevant(pd, weights, use_rotation)) {
364  continue;
365  }
366 
367  add_effector_evaluation(&effectors, depsgraph, scene, ob, psys, pd);
368  }
369  else {
370  /* Object effector. */
371  if (ob == ob_src) {
372  continue;
373  }
374  if (!is_effector_relevant(ob->pd, weights, use_rotation)) {
375  continue;
376  }
378  continue;
379  }
380 
381  add_effector_evaluation(&effectors, depsgraph, scene, ob, NULL, ob->pd);
382  }
383  }
384 
385  return effectors;
386 }
387 
389 {
390  if (lb) {
391  LISTBASE_FOREACH (EffectorCache *, eff, lb) {
392  if (eff->guide_data) {
393  MEM_freeN(eff->guide_data);
394  }
395  }
396 
397  BLI_freelistN(lb);
398  MEM_freeN(lb);
399  }
400 }
401 
403  ParticleData *pa,
405  EffectedPoint *point)
406 {
407  ParticleSettings *part = sim->psys->part;
408  point->loc = state->co;
409  point->vel = state->vel;
410  point->index = pa - sim->psys->particles;
411  point->size = pa->size;
412  point->charge = 0.0f;
413 
414  if (part->pd && part->pd->forcefield == PFIELD_CHARGE) {
415  point->charge += part->pd->f_strength;
416  }
417 
418  if (part->pd2 && part->pd2->forcefield == PFIELD_CHARGE) {
419  point->charge += part->pd2->f_strength;
420  }
421 
422  point->vel_to_sec = 1.0f;
423  point->vel_to_frame = psys_get_timestep(sim);
424 
425  point->flag = 0;
426 
427  if (sim->psys->part->flag & PART_ROT_DYN) {
428  point->ave = state->ave;
429  point->rot = state->rot;
430  }
431  else {
432  point->ave = point->rot = NULL;
433  }
434 
435  point->psys = sim->psys;
436 }
437 
438 void pd_point_from_loc(Scene *scene, float *loc, float *vel, int index, EffectedPoint *point)
439 {
440  point->loc = loc;
441  point->vel = vel;
442  point->index = index;
443  point->size = 0.0f;
444 
445  point->vel_to_sec = (float)scene->r.frs_sec;
446  point->vel_to_frame = 1.0f;
447 
448  point->flag = 0;
449 
450  point->ave = point->rot = NULL;
451  point->psys = NULL;
452 }
453 void pd_point_from_soft(Scene *scene, float *loc, float *vel, int index, EffectedPoint *point)
454 {
455  point->loc = loc;
456  point->vel = vel;
457  point->index = index;
458  point->size = 0.0f;
459 
460  point->vel_to_sec = (float)scene->r.frs_sec;
461  point->vel_to_frame = 1.0f;
462 
463  point->flag = PE_WIND_AS_SPEED;
464 
465  point->ave = point->rot = NULL;
466 
467  point->psys = NULL;
468 }
469 /************************************************/
470 /* Effectors */
471 /************************************************/
472 
473 // triangle - ray callback function
474 static void eff_tri_ray_hit(void *UNUSED(userData),
475  int UNUSED(index),
476  const BVHTreeRay *UNUSED(ray),
477  BVHTreeRayHit *hit)
478 {
479  /* whenever we hit a bounding box, we don't check further */
480  hit->dist = -1;
481  hit->index = 1;
482 }
483 
484 // get visibility of a wind ray
485 static float eff_calc_visibility(ListBase *colliders,
486  EffectorCache *eff,
487  EffectorData *efd,
488  EffectedPoint *point)
489 {
490  const int raycast_flag = BVH_RAYCAST_DEFAULT & ~BVH_RAYCAST_WATERTIGHT;
491  ListBase *colls = colliders;
493  float norm[3], len = 0.0;
494  float visibility = 1.0, absorption = 0.0;
495 
496  if (!(eff->pd->flag & PFIELD_VISIBILITY)) {
497  return visibility;
498  }
499  if (!colls) {
500  colls = BKE_collider_cache_create(eff->depsgraph, eff->ob, NULL);
501  }
502  if (!colls) {
503  return visibility;
504  }
505 
507  len = normalize_v3(norm);
508 
509  /* check all collision objects */
510  for (col = colls->first; col; col = col->next) {
511  CollisionModifierData *collmd = col->collmd;
512 
513  if (col->ob == eff->ob) {
514  continue;
515  }
516  if (collmd->bvhtree) {
517  BVHTreeRayHit hit;
518 
519  hit.index = -1;
520  hit.dist = len + FLT_EPSILON;
521 
522  /* check if the way is blocked */
523  if (BLI_bvhtree_ray_cast_ex(collmd->bvhtree,
524  point->loc,
525  norm,
526  0.0f,
527  &hit,
529  NULL,
530  raycast_flag) != -1) {
531  absorption = col->ob->pd->absorption;
532 
533  /* visibility is only between 0 and 1, calculated from 1-absorption */
534  visibility *= CLAMPIS(1.0f - absorption, 0.0f, 1.0f);
535 
536  if (visibility <= 0.0f) {
537  break;
538  }
539  }
540  }
541  }
542 
543  if (!colliders) {
544  BKE_collider_cache_free(&colls);
545  }
546 
547  return visibility;
548 }
549 
550 // noise function for wind e.g.
551 static float wind_func(struct RNG *rng, float strength)
552 {
553  int random = (BLI_rng_get_int(rng) + 1) % 128; /* max 2357 */
554  float force = BLI_rng_get_float(rng) + 1.0f;
555  float ret;
556  float sign = 0;
557 
558  /* Dividing by 2 is not giving equal sign distribution. */
559  sign = ((float)random > 64.0f) ? 1.0f : -1.0f;
560 
561  ret = sign * ((float)random / force) * strength / 128.0f;
562 
563  return ret;
564 }
565 
566 /* maxdist: zero effect from this distance outwards (if usemax) */
567 /* mindist: full effect up to this distance (if usemin) */
568 /* power: falloff with formula 1/r^power */
569 static float falloff_func(
570  float fac, int usemin, float mindist, int usemax, float maxdist, float power)
571 {
572  /* first quick checks */
573  if (usemax && fac > maxdist) {
574  return 0.0f;
575  }
576 
577  if (usemin && fac < mindist) {
578  return 1.0f;
579  }
580 
581  if (!usemin) {
582  mindist = 0.0;
583  }
584 
585  return pow((double)(1.0f + fac - mindist), (double)(-power));
586 }
587 
588 static float falloff_func_dist(PartDeflect *pd, float fac)
589 {
590  return falloff_func(fac,
591  pd->flag & PFIELD_USEMIN,
592  pd->mindist,
593  pd->flag & PFIELD_USEMAX,
594  pd->maxdist,
595  pd->f_power);
596 }
597 
598 static float falloff_func_rad(PartDeflect *pd, float fac)
599 {
600  return falloff_func(fac,
601  pd->flag & PFIELD_USEMINR,
602  pd->minrad,
603  pd->flag & PFIELD_USEMAXR,
604  pd->maxrad,
605  pd->f_power_r);
606 }
607 
609  EffectorData *efd,
610  EffectedPoint *UNUSED(point),
611  EffectorWeights *weights)
612 {
613  float temp[3];
614  float falloff = weights ? weights->weight[0] * weights->weight[eff->pd->forcefield] : 1.0f;
615  float fac, r_fac;
616 
617  fac = dot_v3v3(efd->nor, efd->vec_to_point2);
618 
619  if (eff->pd->zdir == PFIELD_Z_POS && fac < 0.0f) {
620  falloff = 0.0f;
621  }
622  else if (eff->pd->zdir == PFIELD_Z_NEG && fac > 0.0f) {
623  falloff = 0.0f;
624  }
625  else {
626  switch (eff->pd->falloff) {
627  case PFIELD_FALL_SPHERE:
628  falloff *= falloff_func_dist(eff->pd, efd->distance);
629  break;
630 
631  case PFIELD_FALL_TUBE:
632  falloff *= falloff_func_dist(eff->pd, fabsf(fac));
633  if (falloff == 0.0f) {
634  break;
635  }
636 
637  madd_v3_v3v3fl(temp, efd->vec_to_point2, efd->nor, -fac);
638  r_fac = len_v3(temp);
639  falloff *= falloff_func_rad(eff->pd, r_fac);
640  break;
641  case PFIELD_FALL_CONE:
642  falloff *= falloff_func_dist(eff->pd, fabsf(fac));
643  if (falloff == 0.0f) {
644  break;
645  }
646 
647  r_fac = RAD2DEGF(saacos(fac / len_v3(efd->vec_to_point2)));
648  falloff *= falloff_func_rad(eff->pd, r_fac);
649 
650  break;
651  }
652  }
653 
654  return falloff;
655 }
656 
658  const float co[3],
659  float surface_co[3],
660  float surface_nor[3],
661  float surface_vel[3])
662 {
663  BVHTreeNearest nearest;
664 
665  nearest.index = -1;
666  nearest.dist_sq = FLT_MAX;
667 
669  surmd->bvhtree->tree, co, &nearest, surmd->bvhtree->nearest_callback, surmd->bvhtree);
670 
671  if (nearest.index != -1) {
672  copy_v3_v3(surface_co, nearest.co);
673 
674  if (surface_nor) {
675  copy_v3_v3(surface_nor, nearest.no);
676  }
677 
678  if (surface_vel) {
679  const MLoop *mloop = surmd->bvhtree->loop;
680  const MLoopTri *lt = &surmd->bvhtree->looptri[nearest.index];
681 
682  copy_v3_v3(surface_vel, surmd->v[mloop[lt->tri[0]].v].co);
683  add_v3_v3(surface_vel, surmd->v[mloop[lt->tri[1]].v].co);
684  add_v3_v3(surface_vel, surmd->v[mloop[lt->tri[2]].v].co);
685 
686  mul_v3_fl(surface_vel, (1.0f / 3.0f));
687  }
688  return 1;
689  }
690 
691  return 0;
692 }
694  EffectorData *efd,
695  EffectedPoint *point,
696  int real_velocity)
697 {
698  float cfra = DEG_get_ctime(eff->depsgraph);
699  int ret = 0;
700 
701  /* In case surface object is in Edit mode when loading the .blend,
702  * surface modifier is never executed and bvhtree never built, see T48415. */
703  if (eff->pd && eff->pd->shape == PFIELD_SHAPE_SURFACE && eff->surmd && eff->surmd->bvhtree) {
704  /* closest point in the object surface is an effector */
705  float vec[3];
706 
707  /* using velocity corrected location allows for easier sliding over effector surface */
708  copy_v3_v3(vec, point->vel);
709  mul_v3_fl(vec, point->vel_to_frame);
710  add_v3_v3(vec, point->loc);
711 
713  eff->surmd, vec, efd->loc, efd->nor, real_velocity ? efd->vel : NULL);
714 
715  efd->size = 0.0f;
716  }
717  else if (eff->pd && eff->pd->shape == PFIELD_SHAPE_POINTS) {
718  /* TODO: hair and points object support */
719  Mesh *me_eval = BKE_object_get_evaluated_mesh(eff->ob);
720  if (me_eval != NULL) {
721  copy_v3_v3(efd->loc, me_eval->mvert[*efd->index].co);
722  normal_short_to_float_v3(efd->nor, me_eval->mvert[*efd->index].no);
723 
724  mul_m4_v3(eff->ob->obmat, efd->loc);
725  mul_mat3_m4_v3(eff->ob->obmat, efd->nor);
726 
727  normalize_v3(efd->nor);
728 
729  efd->size = 0.0f;
730 
731  ret = 1;
732  }
733  }
734  else if (eff->psys) {
735  ParticleData *pa = eff->psys->particles + *efd->index;
737 
738  /* exclude the particle itself for self effecting particles */
739  if (eff->psys == point->psys && *efd->index == point->index) {
740  /* pass */
741  }
742  else {
744  sim.depsgraph = eff->depsgraph;
745  sim.scene = eff->scene;
746  sim.ob = eff->ob;
747  sim.psys = eff->psys;
748 
749  /* TODO: time from actual previous calculated frame (step might not be 1) */
750  state.time = cfra - 1.0f;
751  ret = psys_get_particle_state(&sim, *efd->index, &state, 0);
752 
753  /* TODO */
754  // if (eff->pd->forcefiled == PFIELD_HARMONIC && ret==0) {
755  // if (pa->dietime < eff->psys->cfra)
756  // eff->flag |= PE_VELOCITY_TO_IMPULSE;
757  //}
758 
759  copy_v3_v3(efd->loc, state.co);
760 
761  /* rather than use the velocity use rotated x-axis (defaults to velocity) */
762  efd->nor[0] = 1.0f;
763  efd->nor[1] = efd->nor[2] = 0.0f;
764  mul_qt_v3(state.rot, efd->nor);
765 
766  if (real_velocity) {
767  copy_v3_v3(efd->vel, state.vel);
768  }
769  efd->size = pa->size;
770  }
771  }
772  else {
773  /* use center of object for distance calculus */
774  const Object *ob = eff->ob;
775 
776  /* use z-axis as normal*/
777  normalize_v3_v3(efd->nor, ob->obmat[2]);
778 
779  if (eff->pd && ELEM(eff->pd->shape, PFIELD_SHAPE_PLANE, PFIELD_SHAPE_LINE)) {
780  float temp[3], translate[3];
781  sub_v3_v3v3(temp, point->loc, ob->obmat[3]);
782  project_v3_v3v3(translate, temp, efd->nor);
783 
784  /* for vortex the shape chooses between old / new force */
785  if (eff->pd->forcefield == PFIELD_VORTEX || eff->pd->shape == PFIELD_SHAPE_LINE) {
786  add_v3_v3v3(efd->loc, ob->obmat[3], translate);
787  }
788  else { /* normally efd->loc is closest point on effector xy-plane */
789  sub_v3_v3v3(efd->loc, point->loc, translate);
790  }
791  }
792  else {
793  copy_v3_v3(efd->loc, ob->obmat[3]);
794  }
795 
796  zero_v3(efd->vel);
797  efd->size = 0.0f;
798 
799  ret = 1;
800  }
801 
802  if (ret) {
803  sub_v3_v3v3(efd->vec_to_point, point->loc, efd->loc);
804  efd->distance = len_v3(efd->vec_to_point);
805 
806  /* Rest length for harmonic effector,
807  * will have to see later if this could be extended to other effectors. */
808  if (eff->pd && eff->pd->forcefield == PFIELD_HARMONIC && eff->pd->f_size) {
809  mul_v3_fl(efd->vec_to_point, (efd->distance - eff->pd->f_size) / efd->distance);
810  }
811 
812  if (eff->flag & PE_USE_NORMAL_DATA) {
814  copy_v3_v3(efd->nor2, efd->nor);
815  }
816  else {
817  /* for some effectors we need the object center every time */
818  sub_v3_v3v3(efd->vec_to_point2, point->loc, eff->ob->obmat[3]);
819  normalize_v3_v3(efd->nor2, eff->ob->obmat[2]);
820  }
821  }
822 
823  return ret;
824 }
825 static void get_effector_tot(
826  EffectorCache *eff, EffectorData *efd, EffectedPoint *point, int *tot, int *p, int *step)
827 {
828  *p = 0;
829  efd->index = p;
830 
831  if (eff->pd->shape == PFIELD_SHAPE_POINTS) {
832  /* TODO: hair and points object support */
833  Mesh *me_eval = BKE_object_get_evaluated_mesh(eff->ob);
834  *tot = me_eval != NULL ? me_eval->totvert : 1;
835 
836  if (*tot && eff->pd->forcefield == PFIELD_HARMONIC && point->index >= 0) {
837  *p = point->index % *tot;
838  *tot = *p + 1;
839  }
840  }
841  else if (eff->psys) {
842  *tot = eff->psys->totpart;
843 
844  if (eff->pd->forcefield == PFIELD_CHARGE) {
845  /* Only the charge of the effected particle is used for
846  * interaction, not fall-offs. If the fall-offs aren't the
847  * same this will be unphysical, but for animation this
848  * could be the wanted behavior. If you want physical
849  * correctness the fall-off should be spherical 2.0 anyways.
850  */
851  efd->charge = eff->pd->f_strength;
852  }
853  else if (eff->pd->forcefield == PFIELD_HARMONIC &&
854  (eff->pd->flag & PFIELD_MULTIPLE_SPRINGS) == 0) {
855  /* every particle is mapped to only one harmonic effector particle */
856  *p = point->index % eff->psys->totpart;
857  *tot = *p + 1;
858  }
859 
860  if (eff->psys->part->effector_amount) {
861  int totpart = eff->psys->totpart;
862  int amount = eff->psys->part->effector_amount;
863 
864  *step = (totpart > amount) ? totpart / amount : 1;
865  }
866  }
867  else {
868  *tot = 1;
869  }
870 }
872  EffectorData *efd,
873  EffectedPoint *point,
874  float *total_force)
875 {
876  TexResult result[4];
877  float tex_co[3], strength, force[3];
878  float nabla = eff->pd->tex_nabla;
879  int hasrgb;
880  short mode = eff->pd->tex_mode;
881  bool scene_color_manage;
882 
883  if (!eff->pd->tex) {
884  return;
885  }
886 
887  result[0].nor = result[1].nor = result[2].nor = result[3].nor = NULL;
888 
889  strength = eff->pd->f_strength * efd->falloff;
890 
891  copy_v3_v3(tex_co, point->loc);
892 
893  if (eff->pd->flag & PFIELD_TEX_OBJECT) {
894  mul_m4_v3(eff->ob->imat, tex_co);
895 
896  if (eff->pd->flag & PFIELD_TEX_2D) {
897  tex_co[2] = 0.0f;
898  }
899  }
900  else if (eff->pd->flag & PFIELD_TEX_2D) {
901  float fac = -dot_v3v3(tex_co, efd->nor);
902  madd_v3_v3fl(tex_co, efd->nor, fac);
903  }
904 
905  scene_color_manage = BKE_scene_check_color_management_enabled(eff->scene);
906 
907  hasrgb = multitex_ext(
908  eff->pd->tex, tex_co, NULL, NULL, 0, result, 0, NULL, scene_color_manage, false);
909 
910  if (hasrgb && mode == PFIELD_TEX_RGB) {
911  force[0] = (0.5f - result->tr) * strength;
912  force[1] = (0.5f - result->tg) * strength;
913  force[2] = (0.5f - result->tb) * strength;
914  }
915  else if (nabla != 0) {
916  strength /= nabla;
917 
918  tex_co[0] += nabla;
919  multitex_ext(
920  eff->pd->tex, tex_co, NULL, NULL, 0, result + 1, 0, NULL, scene_color_manage, false);
921 
922  tex_co[0] -= nabla;
923  tex_co[1] += nabla;
924  multitex_ext(
925  eff->pd->tex, tex_co, NULL, NULL, 0, result + 2, 0, NULL, scene_color_manage, false);
926 
927  tex_co[1] -= nabla;
928  tex_co[2] += nabla;
929  multitex_ext(
930  eff->pd->tex, tex_co, NULL, NULL, 0, result + 3, 0, NULL, scene_color_manage, false);
931 
932  if (mode == PFIELD_TEX_GRAD || !hasrgb) { /* if we don't have rgb fall back to grad */
933  /* generate intensity if texture only has rgb value */
934  if (hasrgb & TEX_RGB) {
935  for (int i = 0; i < 4; i++) {
936  result[i].tin = (1.0f / 3.0f) * (result[i].tr + result[i].tg + result[i].tb);
937  }
938  }
939  force[0] = (result[0].tin - result[1].tin) * strength;
940  force[1] = (result[0].tin - result[2].tin) * strength;
941  force[2] = (result[0].tin - result[3].tin) * strength;
942  }
943  else { /*PFIELD_TEX_CURL*/
944  float dbdy, dgdz, drdz, dbdx, dgdx, drdy;
945 
946  dbdy = result[2].tb - result[0].tb;
947  dgdz = result[3].tg - result[0].tg;
948  drdz = result[3].tr - result[0].tr;
949  dbdx = result[1].tb - result[0].tb;
950  dgdx = result[1].tg - result[0].tg;
951  drdy = result[2].tr - result[0].tr;
952 
953  force[0] = (dbdy - dgdz) * strength;
954  force[1] = (drdz - dbdx) * strength;
955  force[2] = (dgdx - drdy) * strength;
956  }
957  }
958  else {
959  zero_v3(force);
960  }
961 
962  if (eff->pd->flag & PFIELD_TEX_2D) {
963  float fac = -dot_v3v3(force, efd->nor);
964  madd_v3_v3fl(force, efd->nor, fac);
965  }
966 
967  if (eff->pd->flag & PFIELD_DO_LOCATION) {
968  add_v3_v3(total_force, force);
969  }
970 }
972  EffectorData *efd,
973  EffectedPoint *point,
974  float *total_force)
975 {
976  PartDeflect *pd = eff->pd;
977  RNG *rng = pd->rng;
978  float force[3] = {0, 0, 0};
979  float temp[3];
980  float fac;
981  float strength = pd->f_strength;
982  float damp = pd->f_damp;
983  float noise_factor = pd->f_noise;
984  float flow_falloff = efd->falloff;
985 
986  if (noise_factor > 0.0f) {
987  strength += wind_func(rng, noise_factor);
988 
990  damp += wind_func(rng, noise_factor);
991  }
992  }
993 
994  copy_v3_v3(force, efd->vec_to_point);
995 
996  switch (pd->forcefield) {
997  case PFIELD_WIND:
998  copy_v3_v3(force, efd->nor);
999  mul_v3_fl(force, strength * efd->falloff);
1000  break;
1001  case PFIELD_FORCE:
1002  normalize_v3(force);
1003  if (pd->flag & PFIELD_GRAVITATION) { /* Option: Multiply by 1/distance^2 */
1004  if (efd->distance < FLT_EPSILON) {
1005  strength = 0.0f;
1006  }
1007  else {
1008  strength *= powf(efd->distance, -2.0f);
1009  }
1010  }
1011  mul_v3_fl(force, strength * efd->falloff);
1012  break;
1013  case PFIELD_VORTEX:
1014  /* old vortex force */
1015  if (pd->shape == PFIELD_SHAPE_POINT) {
1016  cross_v3_v3v3(force, efd->nor, efd->vec_to_point);
1017  normalize_v3(force);
1018  mul_v3_fl(force, strength * efd->distance * efd->falloff);
1019  }
1020  else {
1021  /* new vortex force */
1022  cross_v3_v3v3(temp, efd->nor2, efd->vec_to_point2);
1023  mul_v3_fl(temp, strength * efd->falloff);
1024 
1025  cross_v3_v3v3(force, efd->nor2, temp);
1026  mul_v3_fl(force, strength * efd->falloff);
1027 
1028  madd_v3_v3fl(temp, point->vel, -point->vel_to_sec);
1029  add_v3_v3(force, temp);
1030  }
1031  break;
1032  case PFIELD_MAGNET:
1034  /* magnetic field of a moving charge */
1035  cross_v3_v3v3(temp, efd->nor, efd->vec_to_point);
1036  }
1037  else {
1038  copy_v3_v3(temp, efd->nor);
1039  }
1040 
1041  normalize_v3(temp);
1042  mul_v3_fl(temp, strength * efd->falloff);
1043  cross_v3_v3v3(force, point->vel, temp);
1044  mul_v3_fl(force, point->vel_to_sec);
1045  break;
1046  case PFIELD_HARMONIC:
1047  mul_v3_fl(force, -strength * efd->falloff);
1048  copy_v3_v3(temp, point->vel);
1049  mul_v3_fl(temp, -damp * 2.0f * sqrtf(fabsf(strength)) * point->vel_to_sec);
1050  add_v3_v3(force, temp);
1051  break;
1052  case PFIELD_CHARGE:
1053  mul_v3_fl(force, point->charge * strength * efd->falloff);
1054  break;
1055  case PFIELD_LENNARDJ:
1056  fac = pow((efd->size + point->size) / efd->distance, 6.0);
1057 
1058  fac = -fac * (1.0f - fac) / efd->distance;
1059 
1060  /* limit the repulsive term drastically to avoid huge forces */
1061  fac = ((fac > 2.0f) ? 2.0f : fac);
1062 
1063  mul_v3_fl(force, strength * fac);
1064  break;
1065  case PFIELD_BOID:
1066  /* Boid field is handled completely in boids code. */
1067  return;
1068  case PFIELD_TURBULENCE:
1069  if (pd->flag & PFIELD_GLOBAL_CO) {
1070  copy_v3_v3(temp, point->loc);
1071  }
1072  else {
1073  add_v3_v3v3(temp, efd->vec_to_point2, efd->nor2);
1074  }
1075  force[0] = -1.0f + 2.0f * BLI_noise_generic_turbulence(
1076  pd->f_size, temp[0], temp[1], temp[2], 2, 0, 2);
1077  force[1] = -1.0f + 2.0f * BLI_noise_generic_turbulence(
1078  pd->f_size, temp[1], temp[2], temp[0], 2, 0, 2);
1079  force[2] = -1.0f + 2.0f * BLI_noise_generic_turbulence(
1080  pd->f_size, temp[2], temp[0], temp[1], 2, 0, 2);
1081  mul_v3_fl(force, strength * efd->falloff);
1082  break;
1083  case PFIELD_DRAG:
1084  copy_v3_v3(force, point->vel);
1085  fac = normalize_v3(force) * point->vel_to_sec;
1086 
1087  strength = MIN2(strength, 2.0f);
1088  damp = MIN2(damp, 2.0f);
1089 
1090  mul_v3_fl(force, -efd->falloff * fac * (strength * fac + damp));
1091  break;
1092  case PFIELD_FLUIDFLOW:
1093  zero_v3(force);
1094  flow_falloff = 0;
1095 #ifdef WITH_FLUID
1096  if (pd->f_source) {
1097  float density;
1098  if ((density = BKE_fluid_get_velocity_at(pd->f_source, point->loc, force)) >= 0.0f) {
1099  float influence = strength * efd->falloff;
1100  if (pd->flag & PFIELD_SMOKE_DENSITY) {
1101  influence *= density;
1102  }
1103  mul_v3_fl(force, influence);
1104  flow_falloff = influence;
1105  }
1106  }
1107 #endif
1108  break;
1109  }
1110 
1111  if (pd->flag & PFIELD_DO_LOCATION) {
1112  madd_v3_v3fl(total_force, force, 1.0f / point->vel_to_sec);
1113 
1114  if (!ELEM(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG) && pd->f_flow != 0.0f) {
1115  madd_v3_v3fl(total_force, point->vel, -pd->f_flow * flow_falloff);
1116  }
1117  }
1118 
1119  if (pd->flag & PFIELD_DO_ROTATION && point->ave && point->rot) {
1120  float xvec[3] = {1.0f, 0.0f, 0.0f};
1121  float dave[3];
1122  mul_qt_v3(point->rot, xvec);
1123  cross_v3_v3v3(dave, xvec, force);
1124  if (pd->f_flow != 0.0f) {
1125  madd_v3_v3fl(dave, point->ave, -pd->f_flow * efd->falloff);
1126  }
1127  add_v3_v3(point->ave, dave);
1128  }
1129 }
1130 
1131 /* -------- BKE_effectors_apply() --------
1132  * generic force/speed system, now used for particles and softbodies
1133  * scene = scene where it runs in, for time and stuff
1134  * lb = listbase with objects that take part in effecting
1135  * opco = global coord, as input
1136  * force = accumulator for force
1137  * wind_force = accumulator for force only acting perpendicular to a surface
1138  * speed = actual current speed which can be altered
1139  * cur_time = "external" time in frames, is constant for static particles
1140  * loc_time = "local" time in frames, range <0-1> for the lifetime of particle
1141  * par_layer = layer the caller is in
1142  * flags = only used for softbody wind now
1143  * guide = old speed of particle
1144  */
1146  ListBase *colliders,
1147  EffectorWeights *weights,
1148  EffectedPoint *point,
1149  float *force,
1150  float *wind_force,
1151  float *impulse)
1152 {
1153  /*
1154  * Modifies the force on a particle according to its
1155  * relation with the effector object
1156  * Different kind of effectors include:
1157  * Force-fields: Gravity-like attractor
1158  * (force power is related to the inverse of distance to the power of a falloff value)
1159  * Vortex fields: swirling effectors
1160  * (particles rotate around Z-axis of the object. otherwise, same relation as)
1161  * (Force-fields, but this is not done through a force/acceleration)
1162  * Guide: particles on a path
1163  * (particles are guided along a curve bezier or old nurbs)
1164  * (is independent of other effectors)
1165  */
1166  EffectorCache *eff;
1167  EffectorData efd;
1168  int p = 0, tot = 1, step = 1;
1169 
1170  /* Cycle through collected objects, get total of (1/(gravity_strength * dist^gravity_power)) */
1171  /* Check for min distance here? (yes would be cool to add that, ton) */
1172 
1173  if (effectors) {
1174  for (eff = effectors->first; eff; eff = eff->next) {
1175  /* object effectors were fully checked to be OK to evaluate! */
1176 
1177  get_effector_tot(eff, &efd, point, &tot, &p, &step);
1178 
1179  for (; p < tot; p += step) {
1180  if (get_effector_data(eff, &efd, point, 0)) {
1181  efd.falloff = effector_falloff(eff, &efd, point, weights);
1182 
1183  if (efd.falloff > 0.0f) {
1184  efd.falloff *= eff_calc_visibility(colliders, eff, &efd, point);
1185  }
1186  if (efd.falloff > 0.0f) {
1187  float out_force[3] = {0, 0, 0};
1188 
1189  if (eff->pd->forcefield == PFIELD_TEXTURE) {
1190  do_texture_effector(eff, &efd, point, out_force);
1191  }
1192  else {
1193  do_physical_effector(eff, &efd, point, out_force);
1194 
1195  /* for softbody backward compatibility */
1196  if (point->flag & PE_WIND_AS_SPEED && impulse) {
1197  sub_v3_v3v3(impulse, impulse, out_force);
1198  }
1199  }
1200 
1201  if (wind_force) {
1202  madd_v3_v3fl(force, out_force, 1.0f - eff->pd->f_wind_factor);
1203  madd_v3_v3fl(wind_force, out_force, eff->pd->f_wind_factor);
1204  }
1205  else {
1206  add_v3_v3(force, out_force);
1207  }
1208  }
1209  }
1210  else if (eff->flag & PE_VELOCITY_TO_IMPULSE && impulse) {
1211  /* special case for harmonic effector */
1212  add_v3_v3v3(impulse, impulse, efd.vel);
1213  }
1214  }
1215  }
1216  }
1217 }
1218 
1219 /* ======== Simulation Debugging ======== */
1220 
1222 
1224 {
1225  return BLI_ghashutil_uinthash((uint)i);
1226 }
1227 
1229 {
1230 #define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
1231 
1232  uint a, b, c;
1233 
1234  a = b = c = 0xdeadbeef + (2 << 2) + 13;
1235  a += kx;
1236  b += ky;
1237 
1238  c ^= b;
1239  c -= rot(b, 14);
1240  a ^= c;
1241  a -= rot(c, 11);
1242  b ^= a;
1243  b -= rot(a, 25);
1244  c ^= b;
1245  c -= rot(b, 16);
1246  a ^= c;
1247  a -= rot(c, 4);
1248  b ^= a;
1249  b -= rot(a, 14);
1250  c ^= b;
1251  c -= rot(b, 24);
1252 
1253  return c;
1254 
1255 #undef rot
1256 }
1257 
1258 static uint debug_element_hash(const void *key)
1259 {
1260  const SimDebugElement *elem = key;
1261  return elem->hash;
1262 }
1263 
1264 static bool debug_element_compare(const void *a, const void *b)
1265 {
1266  const SimDebugElement *elem1 = a;
1267  const SimDebugElement *elem2 = b;
1268 
1269  if (elem1->hash == elem2->hash) {
1270  return false;
1271  }
1272  return true;
1273 }
1274 
1275 static void debug_element_free(void *val)
1276 {
1277  SimDebugElement *elem = val;
1278  MEM_freeN(elem);
1279 }
1280 
1282 {
1283  if (enable) {
1284  if (!_sim_debug_data) {
1285  _sim_debug_data = MEM_callocN(sizeof(SimDebugData), "sim debug data");
1287  debug_element_hash, debug_element_compare, "sim debug element hash");
1288  }
1289  }
1290  else {
1292  }
1293 }
1294 
1296 {
1297  return _sim_debug_data != NULL;
1298 }
1299 
1301 {
1302  if (_sim_debug_data) {
1303  if (_sim_debug_data->gh) {
1305  }
1307  }
1308 }
1309 
1310 static void debug_data_insert(SimDebugData *debug_data, SimDebugElement *elem)
1311 {
1312  SimDebugElement *old_elem = BLI_ghash_lookup(debug_data->gh, elem);
1313  if (old_elem) {
1314  *old_elem = *elem;
1315  MEM_freeN(elem);
1316  }
1317  else {
1318  BLI_ghash_insert(debug_data->gh, elem, elem);
1319  }
1320 }
1321 
1323  const float v1[3],
1324  const float v2[3],
1325  const char *str,
1326  float r,
1327  float g,
1328  float b,
1329  const char *category,
1330  uint hash)
1331 {
1332  uint category_hash = BLI_ghashutil_strhash_p(category);
1333  SimDebugElement *elem;
1334 
1335  if (!_sim_debug_data) {
1336  if (G.debug & G_DEBUG_SIMDATA) {
1338  }
1339  else {
1340  return;
1341  }
1342  }
1343 
1344  elem = MEM_callocN(sizeof(SimDebugElement), "sim debug data element");
1345  elem->type = type;
1346  elem->category_hash = category_hash;
1347  elem->hash = hash;
1348  elem->color[0] = r;
1349  elem->color[1] = g;
1350  elem->color[2] = b;
1351  if (v1) {
1352  copy_v3_v3(elem->v1, v1);
1353  }
1354  else {
1355  zero_v3(elem->v1);
1356  }
1357  if (v2) {
1358  copy_v3_v3(elem->v2, v2);
1359  }
1360  else {
1361  zero_v3(elem->v2);
1362  }
1363  if (str) {
1364  BLI_strncpy(elem->str, str, sizeof(elem->str));
1365  }
1366  else {
1367  elem->str[0] = '\0';
1368  }
1369 
1371 }
1372 
1374 {
1375  SimDebugElement dummy;
1376  if (!_sim_debug_data) {
1377  return;
1378  }
1379  dummy.hash = hash;
1381 }
1382 
1384 {
1385  if (!_sim_debug_data) {
1386  return;
1387  }
1388  if (_sim_debug_data->gh) {
1390  }
1391 }
1392 
1393 void BKE_sim_debug_data_clear_category(const char *category)
1394 {
1395  int category_hash = (int)BLI_ghashutil_strhash_p(category);
1396 
1397  if (!_sim_debug_data) {
1398  return;
1399  }
1400 
1401  if (_sim_debug_data->gh) {
1402  GHashIterator iter;
1404  while (!BLI_ghashIterator_done(&iter)) {
1405  const SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
1406 
1407  /* Removing invalidates the current iterator, so step before removing. */
1408  BLI_ghashIterator_step(&iter);
1409 
1410  if (elem->category_hash == category_hash) {
1412  }
1413  }
1414  }
1415 }
typedef float(TangentPoint)[2]
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 Base * BKE_collection_or_layer_objects(const struct ViewLayer *view_layer, struct Collection *collection)
void BKE_collider_cache_free(struct ListBase **colliders)
Definition: collision.c:1383
struct ListBase * BKE_collider_cache_create(struct Depsgraph *depsgraph, struct Object *self, struct Collection *collection)
Definition: collision.c:1346
display list (or rather multi purpose list) stuff.
void BKE_displist_make_curveTypes(struct Depsgraph *depsgraph, const struct Scene *scene, struct Object *ob, const bool for_render, const bool for_orco)
#define PE_VELOCITY_TO_IMPULSE
Definition: BKE_effect.h:174
#define PE_USE_NORMAL_DATA
Definition: BKE_effect.h:171
#define PE_WIND_AS_SPEED
Definition: BKE_effect.h:170
float BKE_fluid_get_velocity_at(struct Object *ob, float position[3], float velocity[3])
@ G_DEBUG_SIMDATA
Definition: BKE_global.h:150
struct ModifierData * BKE_modifiers_findby_type(const struct Object *ob, ModifierType type)
General operations, lookup, etc. for blender objects.
struct Mesh * BKE_object_get_evaluated_mesh(struct Object *object)
Definition: object.c:4459
float psys_get_timestep(struct ParticleSimulationData *sim)
Definition: particle.c:4459
int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, int always)
Definition: particle.c:4854
void psys_update_particle_tree(struct ParticleSystem *psys, float cfra)
bool psys_check_enabled(struct Object *ob, struct ParticleSystem *psys, const bool use_render_params)
Definition: particle.c:789
bool BKE_scene_check_color_management_enabled(const struct Scene *scene)
unsigned int BLI_ghashutil_uinthash(unsigned int key)
void BLI_ghashIterator_step(GHashIterator *ghi)
Definition: BLI_ghash.c:1086
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:996
BLI_INLINE bool BLI_ghashIterator_done(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:158
BLI_INLINE void * BLI_ghashIterator_getValue(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:150
unsigned int BLI_ghashutil_strhash_p(const void *ptr)
GHash * BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:718
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:900
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:756
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:1008
void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh)
Definition: BLI_ghash.c:1065
void * BLI_ghash_lookup(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:803
#define BVH_RAYCAST_DEFAULT
Definition: BLI_kdopbvh.h:104
int BLI_bvhtree_ray_cast_ex(BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata, int flag)
Definition: BLI_kdopbvh.c:1939
@ BVH_RAYCAST_WATERTIGHT
Definition: BLI_kdopbvh.h:102
int BLI_bvhtree_find_nearest(BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata)
Definition: BLI_kdopbvh.c:1654
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
void * BLI_findstring(const struct ListBase *listbase, const char *id, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
MINLINE float saacos(float fac)
void mul_mat3_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:794
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
void mul_qt_v3(const float q[4], float r[3])
Definition: math_rotation.c:97
#define RAD2DEGF(_rad)
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_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void normal_short_to_float_v3(float r[3], const short n[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
void project_v3_v3v3(float out[3], const float p[3], const float v_proj[3])
Definition: math_vector.c:674
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
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
float BLI_noise_generic_turbulence(float noisesize, float x, float y, float z, int oct, bool hard, int noisebasis)
Definition: noise.c:1230
Random number functions.
void int BLI_rng_get_int(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition: rand.cc:99
void BLI_rng_srandom(struct RNG *rng, unsigned int seed) ATTR_NONNULL(1)
Definition: rand.cc:89
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1)
Definition: rand.cc:76
struct RNG * BLI_rng_new(unsigned int seed)
Definition: rand.cc:54
float BLI_rng_get_float(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition: rand.cc:120
struct RNG * BLI_rng_copy(struct RNG *rng) ATTR_NONNULL(1)
Definition: rand.cc:71
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
unsigned int uint
Definition: BLI_sys_types.h:83
#define CLAMPIS(a, b, c)
#define UNUSED(x)
#define ELEM(...)
#define MIN2(a, b)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
@ DAG_EVAL_RENDER
Definition: DEG_depsgraph.h:62
struct ListBase * DEG_get_effector_relations(const struct Depsgraph *depsgraph, struct Collection *collection)
float DEG_get_ctime(const Depsgraph *graph)
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
struct ID * DEG_get_evaluated_id(const struct Depsgraph *depsgraph, struct ID *id)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
Object groups, one object can be in many groups at once.
@ CU_PATH
@ BASE_ENABLED_RENDER
@ BASE_ENABLED_VIEWPORT
These structs are the foundation for all linked lists in the library system.
@ eModifierType_Surface
#define PFIELD_SHAPE_LINE
#define PFIELD_SHAPE_SURFACE
#define PFIELD_VISIBILITY
#define PFIELD_USEMINR
#define PFIELD_FALL_CONE
#define PFIELD_USEMIN
#define PFIELD_SHAPE_POINT
@ NUM_PFIELD_TYPES
@ PFIELD_MAGNET
@ PFIELD_FLUIDFLOW
@ PFIELD_FORCE
@ PFIELD_CHARGE
@ PFIELD_HARMONIC
@ PFIELD_TURBULENCE
@ PFIELD_GUIDE
@ PFIELD_LENNARDJ
@ PFIELD_VORTEX
@ PFIELD_TEXTURE
#define PFIELD_Z_POS
#define PFIELD_SHAPE_PLANE
#define PFIELD_SHAPE_POINTS
#define PFIELD_TEX_GRAD
#define PFIELD_MULTIPLE_SPRINGS
#define PFIELD_DO_LOCATION
#define PFIELD_TEX_2D
#define PFIELD_GLOBAL_CO
#define PFIELD_FALL_TUBE
#define PFIELD_TEX_OBJECT
#define PFIELD_Z_NEG
#define PFIELD_DO_ROTATION
#define PFIELD_USEMAXR
#define PFIELD_CLOTH_USE_CULLING
#define PFIELD_TEX_RGB
#define PFIELD_FALL_SPHERE
#define PFIELD_SMOKE_DENSITY
#define PFIELD_USEMAX
#define PFIELD_GRAVITATION
Object is a sort of wrapper for general info.
@ OB_CURVE
#define PART_SELF_EFFECT
#define PART_ROT_DYN
#define TEX_RGB
_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 GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_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 v1
Read Guarded memory(de)allocation.
Platform independent time functions.
ATTR_WARN_UNUSED_RESULT const BMVert * v2
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
Definition: btVector3.h:263
Scene scene
const Depsgraph * depsgraph
ListBase * BKE_effectors_create(Depsgraph *depsgraph, Object *ob_src, ParticleSystem *psys_src, EffectorWeights *weights, bool use_rotation)
Definition: effect.c:333
void BKE_sim_debug_data_add_element(int type, const float v1[3], const float v2[3], const char *str, float r, float g, float b, const char *category, uint hash)
Definition: effect.c:1322
static float wind_func(struct RNG *rng, float strength)
Definition: effect.c:551
static bool is_effector_relevant(PartDeflect *pd, EffectorWeights *weights, bool use_rotation)
Definition: effect.c:326
void BKE_sim_debug_data_clear_category(const char *category)
Definition: effect.c:1393
static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, float *total_force)
Definition: effect.c:871
static void debug_data_insert(SimDebugData *debug_data, SimDebugElement *elem)
Definition: effect.c:1310
SimDebugData * _sim_debug_data
Definition: effect.c:1221
EffectorWeights * BKE_effector_add_weights(Collection *collection)
Definition: effect.c:73
bool BKE_sim_debug_data_get_enabled(void)
Definition: effect.c:1295
void BKE_effectors_free(ListBase *lb)
Definition: effect.c:388
static bool is_effector_enabled(PartDeflect *pd, bool use_rotation)
Definition: effect.c:274
uint BKE_sim_debug_data_hash(int i)
Definition: effect.c:1223
static uint debug_element_hash(const void *key)
Definition: effect.c:1258
static bool debug_element_compare(const void *a, const void *b)
Definition: effect.c:1264
void pd_point_from_loc(Scene *scene, float *loc, float *vel, int index, EffectedPoint *point)
Definition: effect.c:438
void pd_point_from_particle(ParticleSimulationData *sim, ParticleData *pa, ParticleKey *state, EffectedPoint *point)
Definition: effect.c:402
static float falloff_func_dist(PartDeflect *pd, float fac)
Definition: effect.c:588
static void do_physical_effector(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, float *total_force)
Definition: effect.c:971
static void add_effector_evaluation(ListBase **effectors, Depsgraph *depsgraph, Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd)
Definition: effect.c:201
PartDeflect * BKE_partdeflect_copy(const struct PartDeflect *pd_src)
Definition: effect.c:125
void BKE_effector_relations_free(ListBase *lb)
Definition: effect.c:265
void BKE_sim_debug_data_set_enabled(bool enable)
Definition: effect.c:1281
void BKE_partdeflect_free(PartDeflect *pd)
Definition: effect.c:137
ListBase * BKE_effector_relations_create(Depsgraph *depsgraph, ViewLayer *view_layer, Collection *collection)
Definition: effect.c:227
void BKE_sim_debug_data_clear(void)
Definition: effect.c:1383
void BKE_sim_debug_data_remove_element(uint hash)
Definition: effect.c:1373
void BKE_sim_debug_data_free(void)
Definition: effect.c:1300
static void eff_tri_ray_hit(void *UNUSED(userData), int UNUSED(index), const BVHTreeRay *UNUSED(ray), BVHTreeRayHit *hit)
Definition: effect.c:474
void BKE_effectors_apply(ListBase *effectors, ListBase *colliders, EffectorWeights *weights, EffectedPoint *point, float *force, float *wind_force, float *impulse)
Definition: effect.c:1145
static void add_effector_relation(ListBase *relations, Object *ob, ParticleSystem *psys, PartDeflect *pd)
Definition: effect.c:188
static void precalculate_effector(struct Depsgraph *depsgraph, EffectorCache *eff)
Definition: effect.c:150
int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, int real_velocity)
Definition: effect.c:693
#define rot(x, k)
static void debug_element_free(void *val)
Definition: effect.c:1275
PartDeflect * BKE_partdeflect_new(int type)
Definition: effect.c:86
static void get_effector_tot(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, int *tot, int *p, int *step)
Definition: effect.c:825
static bool is_effector_nonzero_strength(PartDeflect *pd)
Definition: effect.c:295
void pd_point_from_soft(Scene *scene, float *loc, float *vel, int index, EffectedPoint *point)
Definition: effect.c:453
int closest_point_on_surface(SurfaceModifierData *surmd, const float co[3], float surface_co[3], float surface_nor[3], float surface_vel[3])
Definition: effect.c:657
float effector_falloff(EffectorCache *eff, EffectorData *efd, EffectedPoint *UNUSED(point), EffectorWeights *weights)
Definition: effect.c:608
uint BKE_sim_debug_data_hash_combine(uint kx, uint ky)
Definition: effect.c:1228
static float eff_calc_visibility(ListBase *colliders, EffectorCache *eff, EffectorData *efd, EffectedPoint *point)
Definition: effect.c:485
static float falloff_func(float fac, int usemin, float mindist, int usemax, float maxdist, float power)
Definition: effect.c:569
static float falloff_func_rad(PartDeflect *pd, float fac)
Definition: effect.c:598
#define str(s)
IMETHOD void random(Vector &a)
addDelta operator for displacement rotational velocity.
Definition: frames.inl:1282
uint col
#define powf(x, y)
#define fabsf(x)
#define sqrtf(x)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static ulong state[N]
static unsigned c
Definition: RandGen.cpp:97
static unsigned a[3]
Definition: RandGen.cpp:92
double sign(double arg)
Definition: utility.h:250
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
Definition: rall1d.h:359
#define hash
Definition: noise.c:169
return ret
closure color absorption() BUILTIN
const struct MLoop * loop
Definition: BKE_bvhutils.h:76
struct BVHTree * tree
Definition: BKE_bvhutils.h:66
BVHTree_NearestPointCallback nearest_callback
Definition: BKE_bvhutils.h:69
const struct MLoopTri * looptri
Definition: BKE_bvhutils.h:77
float co[3]
Definition: BLI_kdopbvh.h:59
float no[3]
Definition: BLI_kdopbvh.h:62
struct Base * next
short flag
struct Object * object
struct BVHTree * bvhtree
const float * anim_path_accum_length
Definition: BKE_curve.h:58
float vel_to_sec
Definition: BKE_effect.h:50
float * vel
Definition: BKE_effect.h:46
struct ParticleSystem * psys
Definition: BKE_effect.h:58
float vel_to_frame
Definition: BKE_effect.h:49
float * loc
Definition: BKE_effect.h:45
unsigned int flag
Definition: BKE_effect.h:55
float * rot
Definition: BKE_effect.h:48
float * ave
Definition: BKE_effect.h:47
float charge
Definition: BKE_effect.h:53
struct ParticleSystem * psys
Definition: BKE_effect.h:91
struct SurfaceModifierData * surmd
Definition: BKE_effect.h:92
float guide_dir[3]
Definition: BKE_effect.h:98
float guide_loc[4]
Definition: BKE_effect.h:98
float guide_radius
Definition: BKE_effect.h:98
struct Scene * scene
Definition: BKE_effect.h:89
struct PartDeflect * pd
Definition: BKE_effect.h:94
struct EffectorCache * next
Definition: BKE_effect.h:86
struct Object * ob
Definition: BKE_effect.h:90
struct Depsgraph * depsgraph
Definition: BKE_effect.h:88
float loc[3]
Definition: BKE_effect.h:68
float distance
Definition: BKE_effect.h:73
float vec_to_point[3]
Definition: BKE_effect.h:72
float vec_to_point2[3]
Definition: BKE_effect.h:79
int * index
Definition: BKE_effect.h:81
float nor[3]
Definition: BKE_effect.h:69
float charge
Definition: BKE_effect.h:76
float falloff
Definition: BKE_effect.h:73
float size
Definition: BKE_effect.h:76
float vel[3]
Definition: BKE_effect.h:70
float nor2[3]
Definition: BKE_effect.h:79
struct ParticleSystem * psys
Definition: BKE_effect.h:108
struct PartDeflect * pd
Definition: BKE_effect.h:109
struct Object * ob
Definition: BKE_effect.h:107
struct Collection * group
void * first
Definition: DNA_listBase.h:47
unsigned int tri[3]
unsigned int v
float co[3]
short no[3]
struct MVert * mvert
int totvert
struct CurveCache * curve_cache
ListBase particlesystem
struct PartDeflect * pd
float imat[4][4]
Object_Runtime runtime
float obmat[4][4]
void * data
struct Object * f_source
struct PartDeflect * pd2
struct PartDeflect * pd
struct Depsgraph * depsgraph
Definition: BKE_particle.h:87
struct Scene * scene
Definition: BKE_particle.h:88
struct ParticleSystem * psys
Definition: BKE_particle.h:90
struct Object * ob
Definition: BKE_particle.h:89
ParticleData * particles
ParticleSettings * part
Definition: rand.cc:48
struct RenderData r
struct GHash * gh
Definition: BKE_effect.h:223
char str[64]
Definition: BKE_effect.h:211
float color[3]
Definition: BKE_effect.h:208
unsigned int category_hash
Definition: BKE_effect.h:204
unsigned int hash
Definition: BKE_effect.h:205
struct BVHTreeFromMesh * bvhtree
int multitex_ext(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, const short thread, struct ImagePool *pool, bool scene_color_manage, const bool skip_load_image)
double PIL_check_seconds_timer(void)
Definition: time.c:80
ccl_device_inline float3 ceil(const float3 &a)
#define G(x, y, z)
uint len