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