Blender  V2.93
texture_pointdensity.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 <math.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 
28 #include "MEM_guardedalloc.h"
29 
30 #include "BLI_blenlib.h"
31 #include "BLI_kdopbvh.h"
32 #include "BLI_math.h"
33 #include "BLI_noise.h"
34 #include "BLI_task.h"
35 #include "BLI_utildefines.h"
36 
37 #include "BLT_translation.h"
38 
39 #include "DNA_mesh_types.h"
40 #include "DNA_meshdata_types.h"
41 #include "DNA_object_types.h"
42 #include "DNA_particle_types.h"
43 #include "DNA_texture_types.h"
44 
45 #include "BKE_colorband.h"
46 #include "BKE_colortools.h"
47 #include "BKE_customdata.h"
48 #include "BKE_deform.h"
49 #include "BKE_lattice.h"
50 #include "BKE_object.h"
51 #include "BKE_particle.h"
52 #include "BKE_scene.h"
53 
54 #include "DEG_depsgraph.h"
55 #include "DEG_depsgraph_query.h"
56 
57 #include "render_types.h"
58 #include "texture_common.h"
59 
60 #include "RE_texture.h"
61 
62 static ThreadMutex sample_mutex = PTHREAD_MUTEX_INITIALIZER;
63 
65 {
66  int pd_bitflag = 0;
67 
68  if (pd->source == TEX_PD_PSYS) {
72  pd_bitflag |= POINT_DATA_VEL;
73  }
74  if ((pd->color_source == TEX_PD_COLOR_PARTAGE) ||
76  pd_bitflag |= POINT_DATA_LIFE;
77  }
78  }
79  else if (pd->source == TEX_PD_OBJECT) {
80  if (ELEM(pd->ob_color_source,
84  pd_bitflag |= POINT_DATA_COLOR;
85  }
86  }
87 
88  return pd_bitflag;
89 }
90 
92  float **r_data_velocity,
93  float **r_data_life,
94  float **r_data_color)
95 {
96  const int data_used = point_data_used(pd);
97  const int totpoint = pd->totpoints;
98  float *data = pd->point_data;
99  int offset = 0;
100 
101  if (data_used & POINT_DATA_VEL) {
102  if (r_data_velocity) {
103  *r_data_velocity = data + offset;
104  }
105  offset += 3 * totpoint;
106  }
107  else {
108  if (r_data_velocity) {
109  *r_data_velocity = NULL;
110  }
111  }
112 
113  if (data_used & POINT_DATA_LIFE) {
114  if (r_data_life) {
115  *r_data_life = data + offset;
116  }
117  offset += totpoint;
118  }
119  else {
120  if (r_data_life) {
121  *r_data_life = NULL;
122  }
123  }
124 
125  if (data_used & POINT_DATA_COLOR) {
126  if (r_data_color) {
127  *r_data_color = data + offset;
128  }
129  offset += 3 * totpoint;
130  }
131  else {
132  if (r_data_color) {
133  *r_data_color = NULL;
134  }
135  }
136 }
137 
138 /* additional data stored alongside the point density BVH,
139  * accessible by point index number to retrieve other information
140  * such as particle velocity or lifetime */
142 {
143  const int totpoints = pd->totpoints;
144  int data_used = point_data_used(pd);
145  int data_size = 0;
146 
147  if (data_used & POINT_DATA_VEL) {
148  /* store 3 channels of velocity data */
149  data_size += 3;
150  }
151  if (data_used & POINT_DATA_LIFE) {
152  /* store 1 channel of lifetime data */
153  data_size += 1;
154  }
155  if (data_used & POINT_DATA_COLOR) {
156  /* store 3 channels of RGB data */
157  data_size += 3;
158  }
159 
160  if (data_size) {
161  pd->point_data = MEM_callocN(sizeof(float) * data_size * totpoints, "particle point data");
162  }
163 }
164 
167 {
169  ParticleCacheKey *cache;
171  ParticleData *pa = NULL;
172  float cfra = BKE_scene_frame_get(scene);
173  int i /*, childexists*/ /* UNUSED */;
174  int total_particles;
175  int data_used;
176  float *data_vel, *data_life;
177  float partco[3];
178  const bool use_render_params = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
179 
180  data_used = point_data_used(pd);
181 
182  if (!psys_check_enabled(ob, psys, use_render_params)) {
183  return;
184  }
185 
186  sim.depsgraph = depsgraph;
187  sim.scene = scene;
188  sim.ob = ob;
189  sim.psys = psys;
190  sim.psmd = psys_get_modifier(ob, psys);
191 
192  /* in case ob->imat isn't up-to-date */
193  invert_m4_m4(ob->imat, ob->obmat);
194 
195  total_particles = psys->totpart + psys->totchild;
197 
198  pd->point_tree = BLI_bvhtree_new(total_particles, 0.0, 4, 6);
199  pd->totpoints = total_particles;
200  alloc_point_data(pd);
201  point_data_pointers(pd, &data_vel, &data_life, NULL);
202 
203 #if 0 /* UNUSED */
204  if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT)) {
205  childexists = 1;
206  }
207 #endif
208 
209  for (i = 0, pa = psys->particles; i < total_particles; i++, pa++) {
210 
211  if (psys->part->type == PART_HAIR) {
212  /* hair particles */
213  if (i < psys->totpart && psys->pathcache) {
214  cache = psys->pathcache[i];
215  }
216  else if (i >= psys->totpart && psys->childcache) {
217  cache = psys->childcache[i - psys->totpart];
218  }
219  else {
220  continue;
221  }
222 
223  cache += cache->segments; /* use endpoint */
224 
225  copy_v3_v3(state.co, cache->co);
226  zero_v3(state.vel);
227  state.time = 0.0f;
228  }
229  else {
230  /* emitter particles */
231  state.time = cfra;
232 
233  if (!psys_get_particle_state(&sim, i, &state, 0)) {
234  continue;
235  }
236 
237  if (data_used & POINT_DATA_LIFE) {
238  if (i < psys->totpart) {
239  state.time = (cfra - pa->time) / pa->lifetime;
240  }
241  else {
242  ChildParticle *cpa = (psys->child + i) - psys->totpart;
243  float pa_birthtime, pa_dietime;
244 
245  state.time = psys_get_child_time(psys, cpa, cfra, &pa_birthtime, &pa_dietime);
246  }
247  }
248  }
249 
250  copy_v3_v3(partco, state.co);
251 
253  mul_m4_v3(ob->imat, partco);
254  }
255  else if (pd->psys_cache_space == TEX_PD_OBJECTLOC) {
256  sub_v3_v3(partco, ob->loc);
257  }
258  else {
259  /* TEX_PD_WORLDSPACE */
260  }
261 
262  BLI_bvhtree_insert(pd->point_tree, i, partco, 1);
263 
264  if (data_vel) {
265  data_vel[i * 3 + 0] = state.vel[0];
266  data_vel[i * 3 + 1] = state.vel[1];
267  data_vel[i * 3 + 2] = state.vel[2];
268  }
269  if (data_life) {
270  data_life[i] = state.time;
271  }
272  }
273 
275 
276  if (psys->lattice_deform_data) {
278  psys->lattice_deform_data = NULL;
279  }
280 }
281 
283  Object *UNUSED(ob),
284  Mesh *mesh,
285  float *data_color)
286 {
287  const MLoop *mloop = mesh->mloop;
288  const int totloop = mesh->totloop;
289  const MLoopCol *mcol;
290  char layername[MAX_CUSTOMDATA_LAYER_NAME];
291  int i;
292 
293  BLI_assert(data_color);
294 
296  return;
297  }
299  mcol = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPCOL, layername);
300  if (!mcol) {
301  return;
302  }
303 
304  /* Stores the number of MLoops using the same vertex, so we can normalize colors. */
305  int *mcorners = MEM_callocN(sizeof(int) * pd->totpoints, "point density corner count");
306 
307  for (i = 0; i < totloop; i++) {
308  int v = mloop[i].v;
309 
310  if (mcorners[v] == 0) {
311  rgb_uchar_to_float(&data_color[v * 3], &mcol[i].r);
312  }
313  else {
314  float col[3];
315  rgb_uchar_to_float(col, &mcol[i].r);
316  add_v3_v3(&data_color[v * 3], col);
317  }
318 
319  ++mcorners[v];
320  }
321 
322  /* Normalize colors by averaging over mcorners.
323  * All the corners share the same vertex, ie. occupy the same point in space.
324  */
325  for (i = 0; i < pd->totpoints; i++) {
326  if (mcorners[i] > 0) {
327  mul_v3_fl(&data_color[i * 3], 1.0f / mcorners[i]);
328  }
329  }
330 
331  MEM_freeN(mcorners);
332 }
333 
335  Object *ob,
336  Mesh *mesh,
337  float *data_color)
338 {
339  const int totvert = mesh->totvert;
340  const MDeformVert *mdef, *dv;
341  int mdef_index;
342  int i;
343 
344  BLI_assert(data_color);
345 
346  mdef = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT);
347  if (!mdef) {
348  return;
349  }
351  if (mdef_index < 0) {
352  mdef_index = ob->actdef - 1;
353  }
354  if (mdef_index < 0) {
355  return;
356  }
357 
358  for (i = 0, dv = mdef; i < totvert; i++, dv++, data_color += 3) {
359  MDeformWeight *dw;
360  int j;
361 
362  for (j = 0, dw = dv->dw; j < dv->totweight; j++, dw++) {
363  if (dw->def_nr == mdef_index) {
364  copy_v3_fl(data_color, dw->weight);
365  break;
366  }
367  }
368  }
369 }
370 
372  Object *UNUSED(ob),
373  Mesh *mesh,
374  float *data_color)
375 {
376  MVert *mvert = mesh->mvert, *mv;
377  int i;
378 
379  BLI_assert(data_color);
380 
381  for (i = 0, mv = mvert; i < pd->totpoints; i++, mv++, data_color += 3) {
382  normal_short_to_float_v3(data_color, mv->no);
383  }
384 }
385 
387 {
388  float *data_color;
389  int i;
390  MVert *mvert = NULL, *mv;
391  Mesh *mesh = ob->data;
392 
393 #if 0 /* UNUSED */
395  mask.fmask |= CD_MASK_MTFACE | CD_MASK_MCOL;
396  switch (pd->ob_color_source) {
398  mask.lmask |= CD_MASK_MLOOPCOL;
399  break;
401  mask.vmask |= CD_MASK_MDEFORMVERT;
402  break;
403  }
404 #endif
405 
406  mvert = mesh->mvert; /* local object space */
407  pd->totpoints = mesh->totvert;
408  if (pd->totpoints == 0) {
409  return;
410  }
411 
412  pd->point_tree = BLI_bvhtree_new(pd->totpoints, 0.0, 4, 6);
413  alloc_point_data(pd);
414  point_data_pointers(pd, NULL, NULL, &data_color);
415 
416  for (i = 0, mv = mvert; i < pd->totpoints; i++, mv++) {
417  float co[3];
418 
419  copy_v3_v3(co, mv->co);
420 
421  switch (pd->ob_cache_space) {
422  case TEX_PD_OBJECTSPACE:
423  break;
424  case TEX_PD_OBJECTLOC:
425  mul_m4_v3(ob->obmat, co);
426  sub_v3_v3(co, ob->loc);
427  break;
428  case TEX_PD_WORLDSPACE:
429  default:
430  mul_m4_v3(ob->obmat, co);
431  break;
432  }
433 
434  BLI_bvhtree_insert(pd->point_tree, i, co, 1);
435  }
436 
437  switch (pd->ob_color_source) {
439  pointdensity_cache_vertex_color(pd, ob, mesh, data_color);
440  break;
442  pointdensity_cache_vertex_weight(pd, ob, mesh, data_color);
443  break;
445  pointdensity_cache_vertex_normal(pd, ob, mesh, data_color);
446  break;
447  }
448 
450 }
451 
453 {
454  if (pd == NULL) {
455  return;
456  }
457 
458  if (pd->point_tree) {
460  pd->point_tree = NULL;
461  }
462 
463  if (pd->source == TEX_PD_PSYS) {
464  Object *ob = pd->object;
465  ParticleSystem *psys;
466 
467  if (!ob || !pd->psys) {
468  return;
469  }
470 
471  psys = BLI_findlink(&ob->particlesystem, pd->psys - 1);
472  if (!psys) {
473  return;
474  }
475 
476  pointdensity_cache_psys(depsgraph, scene, pd, ob, psys);
477  }
478  else if (pd->source == TEX_PD_OBJECT) {
479  Object *ob = pd->object;
480  if (ob && ob->type == OB_MESH) {
482  }
483  }
484 }
485 
487 {
488  if (pd == NULL) {
489  return;
490  }
491 
492  if (pd->point_tree) {
494  pd->point_tree = NULL;
495  }
496 
497  if (pd->point_data) {
498  MEM_freeN(pd->point_data);
499  pd->point_data = NULL;
500  }
501  pd->totpoints = 0;
502 }
503 
504 typedef struct PointDensityRangeData {
505  float *density;
510  float *vec;
511  float *col;
512  float softness;
515  float *age;
517  float velscale;
519 
520 static float density_falloff(PointDensityRangeData *pdr, int index, float squared_dist)
521 {
522  const float dist = (pdr->squared_radius - squared_dist) / pdr->squared_radius * 0.5f;
523  float density = 0.0f;
524 
525  switch (pdr->falloff_type) {
526  case TEX_PD_FALLOFF_STD:
527  density = dist;
528  break;
530  density = 3.0f * dist * dist - 2.0f * dist * dist * dist;
531  break;
532  case TEX_PD_FALLOFF_SOFT:
533  density = pow(dist, pdr->softness);
534  break;
536  density = pdr->squared_radius;
537  break;
538  case TEX_PD_FALLOFF_ROOT:
539  density = sqrtf(dist);
540  break;
542  if (pdr->point_data_life) {
543  density = dist * MIN2(pdr->point_data_life[index], 1.0f);
544  }
545  else {
546  density = dist;
547  }
548  break;
550  if (pdr->point_data_velocity) {
551  density = dist * len_v3(&pdr->point_data_velocity[index * 3]) * pdr->velscale;
552  }
553  else {
554  density = dist;
555  }
556  break;
557  }
558 
559  if (pdr->density_curve && dist != 0.0f) {
561  density = BKE_curvemapping_evaluateF(pdr->density_curve, 0, density / dist) * dist;
562  }
563 
564  return density;
565 }
566 
567 static void accum_density(void *userdata, int index, const float co[3], float squared_dist)
568 {
569  PointDensityRangeData *pdr = (PointDensityRangeData *)userdata;
570  float density = 0.0f;
571 
572  UNUSED_VARS(co);
573 
574  if (pdr->point_data_velocity) {
575  pdr->vec[0] += pdr->point_data_velocity[index * 3 + 0]; // * density;
576  pdr->vec[1] += pdr->point_data_velocity[index * 3 + 1]; // * density;
577  pdr->vec[2] += pdr->point_data_velocity[index * 3 + 2]; // * density;
578  }
579  if (pdr->point_data_life) {
580  *pdr->age += pdr->point_data_life[index]; // * density;
581  }
582  if (pdr->point_data_color) {
583  add_v3_v3(pdr->col, &pdr->point_data_color[index * 3]); // * density;
584  }
585 
586  density = density_falloff(pdr, index, squared_dist);
587 
588  *pdr->density += density;
589 }
590 
593  float *density,
594  float *vec,
595  float *age,
596  float *col,
597  struct CurveMapping *density_curve,
598  float velscale)
599 {
600  pdr->squared_radius = pd->radius * pd->radius;
601  pdr->density = density;
602  pdr->falloff_type = pd->falloff_type;
603  pdr->vec = vec;
604  pdr->age = age;
605  pdr->col = col;
606  pdr->softness = pd->falloff_softness;
607  pdr->noise_influence = pd->noise_influence;
609  pd, &pdr->point_data_velocity, &pdr->point_data_life, &pdr->point_data_color);
610  pdr->density_curve = density_curve;
611  pdr->velscale = velscale;
612 }
613 
614 static int pointdensity(PointDensity *pd,
615  const float texvec[3],
616  TexResult *texres,
617  float r_vec[3],
618  float *r_age,
619  float r_col[3])
620 {
621  int retval = TEX_INT;
623  float density = 0.0f, age = 0.0f;
624  float vec[3] = {0.0f, 0.0f, 0.0f}, col[3] = {0.0f, 0.0f, 0.0f}, co[3];
625  float turb, noise_fac;
626  int num = 0;
627 
628  texres->tin = 0.0f;
629 
631  &pdr,
632  &density,
633  vec,
634  &age,
635  col,
637  pd->falloff_speed_scale * 0.001f);
638  noise_fac = pd->noise_fac * 0.5f; /* better default */
639 
640  copy_v3_v3(co, texvec);
641 
642  if (point_data_used(pd)) {
643  /* does a BVH lookup to find accumulated density and additional point data *
644  * stores particle velocity vector in 'vec', and particle lifetime in 'time' */
645  num = BLI_bvhtree_range_query(pd->point_tree, co, pd->radius, accum_density, &pdr);
646  if (num > 0) {
647  age /= num;
648  mul_v3_fl(vec, 1.0f / num);
649  mul_v3_fl(col, 1.0f / num);
650  }
651 
652  /* reset */
653  density = 0.0f;
654  zero_v3(vec);
655  zero_v3(col);
656  }
657 
658  if (pd->flag & TEX_PD_TURBULENCE) {
660  texvec[0] + vec[0],
661  texvec[1] + vec[1],
662  texvec[2] + vec[2],
663  pd->noise_depth,
664  0,
665  pd->noise_basis);
666 
667  turb -= 0.5f; /* re-center 0.0-1.0 range around 0 to prevent offsetting result */
668 
669  /* now we have an offset coordinate to use for the density lookup */
670  co[0] = texvec[0] + noise_fac * turb;
671  co[1] = texvec[1] + noise_fac * turb;
672  co[2] = texvec[2] + noise_fac * turb;
673  }
674 
675  /* BVH query with the potentially perturbed coordinates */
676  num = BLI_bvhtree_range_query(pd->point_tree, co, pd->radius, accum_density, &pdr);
677  if (num > 0) {
678  age /= num;
679  mul_v3_fl(vec, 1.0f / num);
680  mul_v3_fl(col, 1.0f / num);
681  }
682 
683  texres->tin = density;
684  if (r_age != NULL) {
685  *r_age = age;
686  }
687  if (r_vec != NULL) {
688  copy_v3_v3(r_vec, vec);
689  }
690  if (r_col != NULL) {
691  copy_v3_v3(r_col, col);
692  }
693 
694  return retval;
695 }
696 
697 static void pointdensity_color(
698  PointDensity *pd, TexResult *texres, float age, const float vec[3], const float col[3])
699 {
700  texres->tr = texres->tg = texres->tb = texres->ta = 1.0f;
701 
702  if (pd->source == TEX_PD_PSYS) {
703  float rgba[4];
704 
705  switch (pd->color_source) {
707  if (pd->coba) {
708  if (BKE_colorband_evaluate(pd->coba, age, rgba)) {
709  texres->talpha = true;
710  copy_v3_v3(&texres->tr, rgba);
711  texres->tin *= rgba[3];
712  texres->ta = texres->tin;
713  }
714  }
715  break;
716  case TEX_PD_COLOR_PARTSPEED: {
717  float speed = len_v3(vec) * pd->speed_scale;
718 
719  if (pd->coba) {
720  if (BKE_colorband_evaluate(pd->coba, speed, rgba)) {
721  texres->talpha = true;
722  copy_v3_v3(&texres->tr, rgba);
723  texres->tin *= rgba[3];
724  texres->ta = texres->tin;
725  }
726  }
727  break;
728  }
730  texres->talpha = true;
731  mul_v3_v3fl(&texres->tr, vec, pd->speed_scale);
732  texres->ta = texres->tin;
733  break;
735  default:
736  break;
737  }
738  }
739  else {
740  float rgba[4];
741 
742  switch (pd->ob_color_source) {
744  texres->talpha = true;
745  copy_v3_v3(&texres->tr, col);
746  texres->ta = texres->tin;
747  break;
749  texres->talpha = true;
750  if (pd->coba && BKE_colorband_evaluate(pd->coba, col[0], rgba)) {
751  copy_v3_v3(&texres->tr, rgba);
752  texres->tin *= rgba[3];
753  }
754  else {
755  copy_v3_v3(&texres->tr, col);
756  }
757  texres->ta = texres->tin;
758  break;
760  texres->talpha = true;
761  copy_v3_v3(&texres->tr, col);
762  texres->ta = texres->tin;
763  break;
765  default:
766  break;
767  }
768  }
769 }
770 
771 static void sample_dummy_point_density(int resolution, float *values)
772 {
773  memset(values, 0, sizeof(float[4]) * resolution * resolution * resolution);
774 }
775 
777  Scene *scene,
778  Object *object,
779  ParticleSystem *psys,
780  float radius,
781  float min[3],
782  float max[3])
783 {
784  const float size[3] = {radius, radius, radius};
785  const float cfra = BKE_scene_frame_get(scene);
786  ParticleSettings *part = psys->part;
788  ParticleData *pa = NULL;
789  int i;
790  int total_particles;
791  float mat[4][4], imat[4][4];
792 
793  INIT_MINMAX(min, max);
794  if (part->type == PART_HAIR) {
795  /* TODO(sergey): Not supported currently. */
796  return;
797  }
798 
799  unit_m4(mat);
800 
801  sim.depsgraph = depsgraph;
802  sim.scene = scene;
803  sim.ob = object;
804  sim.psys = psys;
805  sim.psmd = psys_get_modifier(object, psys);
806 
807  invert_m4_m4(imat, object->obmat);
808  total_particles = psys->totpart + psys->totchild;
810 
811  for (i = 0, pa = psys->particles; i < total_particles; i++, pa++) {
812  float co_object[3], co_min[3], co_max[3];
814  state.time = cfra;
815  if (!psys_get_particle_state(&sim, i, &state, 0)) {
816  continue;
817  }
818  mul_v3_m4v3(co_object, imat, state.co);
819  sub_v3_v3v3(co_min, co_object, size);
820  add_v3_v3v3(co_max, co_object, size);
821  minmax_v3v3_v3(min, max, co_min);
822  minmax_v3v3_v3(min, max, co_max);
823  }
824 
825  if (psys->lattice_deform_data) {
827  psys->lattice_deform_data = NULL;
828  }
829 }
830 
832 {
834 
835  /* Same matrices/resolution as dupli_render_particle_set(). */
839 }
840 
842  struct PointDensity *pd,
843  float r_min[3],
844  float r_max[3])
845 {
847  Object *object = pd->object;
848  if (object == NULL) {
849  zero_v3(r_min);
850  zero_v3(r_max);
851  return;
852  }
853  if (pd->source == TEX_PD_PSYS) {
854  ParticleSystem *psys;
855 
856  if (pd->psys == 0) {
857  zero_v3(r_min);
858  zero_v3(r_max);
859  return;
860  }
861  psys = BLI_findlink(&object->particlesystem, pd->psys - 1);
862  if (psys == NULL) {
863  zero_v3(r_min);
864  zero_v3(r_max);
865  return;
866  }
867 
868  particle_system_minmax(depsgraph, scene, object, psys, pd->radius, r_min, r_max);
869  }
870  else {
871  const float radius[3] = {pd->radius, pd->radius, pd->radius};
872  BoundBox *bb = BKE_object_boundbox_get(object);
873 
874  if (bb != NULL) {
875  BLI_assert((bb->flag & BOUNDBOX_DIRTY) == 0);
876  copy_v3_v3(r_min, bb->vec[0]);
877  copy_v3_v3(r_max, bb->vec[6]);
878  /* Adjust texture space to include density points on the boundaries. */
879  sub_v3_v3(r_min, radius);
880  add_v3_v3(r_max, radius);
881  }
882  else {
883  zero_v3(r_min);
884  zero_v3(r_max);
885  }
886  }
887 }
888 
889 typedef struct SampleCallbackData {
892  float *min, *dim;
893  float *values;
895 
896 static void point_density_sample_func(void *__restrict data_v,
897  const int iter,
898  const TaskParallelTLS *__restrict UNUSED(tls))
899 {
901 
902  const int resolution = data->resolution;
903  const int resolution2 = resolution * resolution;
904  const float *min = data->min, *dim = data->dim;
905  PointDensity *pd = data->pd;
906  float *values = data->values;
907 
908  if (!pd || !pd->point_tree) {
909  return;
910  }
911 
912  size_t z = (size_t)iter;
913  for (size_t y = 0; y < resolution; y++) {
914  for (size_t x = 0; x < resolution; x++) {
915  size_t index = z * resolution2 + y * resolution + x;
916  float texvec[3];
917  float age, vec[3], col[3];
918  TexResult texres;
919 
920  copy_v3_v3(texvec, min);
921  texvec[0] += dim[0] * (float)x / (float)resolution;
922  texvec[1] += dim[1] * (float)y / (float)resolution;
923  texvec[2] += dim[2] * (float)z / (float)resolution;
924 
925  pointdensity(pd, texvec, &texres, vec, &age, col);
926  pointdensity_color(pd, &texres, age, vec, col);
927 
928  copy_v3_v3(&values[index * 4 + 0], &texres.tr);
929  values[index * 4 + 3] = texres.tin;
930  }
931  }
932 }
933 
934 /* NOTE 1: Requires RE_point_density_cache() to be called first.
935  * NOTE 2: Frees point density structure after sampling.
936  */
938  PointDensity *pd,
939  const int resolution,
940  float *values)
941 {
942  Object *object = pd->object;
943  float min[3], max[3], dim[3];
944 
945  /* TODO(sergey): Implement some sort of assert() that point density
946  * was cached already.
947  */
948 
949  if (object == NULL) {
950  sample_dummy_point_density(resolution, values);
951  return;
952  }
953 
957  sub_v3_v3v3(dim, max, min);
958  if (dim[0] <= 0.0f || dim[1] <= 0.0f || dim[2] <= 0.0f) {
959  sample_dummy_point_density(resolution, values);
960  return;
961  }
962 
964  data.pd = pd;
965  data.resolution = resolution;
966  data.min = min;
967  data.dim = dim;
968  data.values = values;
969  TaskParallelSettings settings;
971  settings.use_threading = (resolution > 32);
972  BLI_task_parallel_range(0, resolution, &data, point_density_sample_func, &settings);
973 
974  free_pointdensity(pd);
975 }
976 
978 {
979  free_pointdensity(pd);
980 }
981 
983 {
984 }
typedef float(TangentPoint)[2]
bool BKE_colorband_evaluate(const struct ColorBand *coba, float in, float out[4])
void BKE_curvemapping_init(struct CurveMapping *cumap)
Definition: colortools.c:1200
float BKE_curvemapping_evaluateF(const struct CurveMapping *cumap, int cur, float value)
CustomData interface, see also DNA_customdata_types.h.
bool CustomData_has_layer(const struct CustomData *data, int type)
const CustomData_MeshMasks CD_MASK_BAREMESH
Definition: customdata.c:1919
void * CustomData_get_layer_named(const struct CustomData *data, int type, const char *name)
Definition: customdata.c:3217
void * CustomData_get_layer(const struct CustomData *data, int type)
void CustomData_validate_layer_name(const struct CustomData *data, int type, const char *name, char *outname)
support for deformation groups and hooks.
int BKE_object_defgroup_name_index(const struct Object *ob, const char *name)
void BKE_lattice_deform_data_destroy(struct LatticeDeformData *lattice_deform_data)
General operations, lookup, etc. for blender objects.
struct BoundBox * BKE_object_boundbox_get(struct Object *ob)
Definition: object.c:3817
struct LatticeDeformData * psys_create_lattice_deform_data(struct ParticleSimulationData *sim)
Definition: particle.c:696
float psys_get_child_time(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *birthtime, float *dietime)
Definition: particle.c:4463
int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, int always)
Definition: particle.c:4854
struct ParticleSystemModifierData * psys_get_modifier(struct Object *ob, struct ParticleSystem *psys)
Definition: particle.c:2201
bool psys_check_enabled(struct Object *ob, struct ParticleSystem *psys, const bool use_render_params)
Definition: particle.c:789
float BKE_scene_frame_get(const struct Scene *scene)
#define BLI_assert(a)
Definition: BLI_assert.h:58
int BLI_bvhtree_range_query(BVHTree *tree, const float co[3], float radius, BVHTree_RangeQuery callback, void *userdata)
Definition: BLI_kdopbvh.c:2131
void BLI_bvhtree_balance(BVHTree *tree)
Definition: BLI_kdopbvh.c:956
BVHTree * BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
Definition: BLI_kdopbvh.c:873
void BLI_bvhtree_free(BVHTree *tree)
Definition: BLI_kdopbvh.c:945
void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints)
Definition: BLI_kdopbvh.c:998
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void rgb_uchar_to_float(float r_col[3], const unsigned char col_ub[3])
Definition: math_color.c:407
void unit_m4(float m[4][4])
Definition: rct.c:1140
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:742
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
Definition: math_vector.c:1020
MINLINE void sub_v3_v3(float r[3], const float a[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 add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void zero_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
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
void BLI_task_parallel_range(const int start, const int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:110
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
Definition: BLI_task.h:231
void BLI_mutex_lock(ThreadMutex *mutex)
Definition: threads.cc:401
void BLI_mutex_unlock(ThreadMutex *mutex)
Definition: threads.cc:406
pthread_mutex_t ThreadMutex
Definition: BLI_threads.h:83
#define INIT_MINMAX(min, max)
#define UNUSED_VARS(...)
#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
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
#define MAX_CUSTOMDATA_LAYER_NAME
#define CD_MASK_MCOL
#define CD_MASK_MDEFORMVERT
#define CD_MASK_MLOOPCOL
@ CD_MDEFORMVERT
@ CD_MLOOPCOL
#define CD_MASK_MTFACE
Object is a sort of wrapper for general info.
@ BOUNDBOX_DIRTY
@ OB_MESH
@ PART_DRAW_PARENT
@ PART_HAIR
#define TEX_PD_TURBULENCE
#define TEX_PD_FALLOFF_PARTICLE_AGE
#define TEX_PD_OBJECTSPACE
#define TEX_PD_OBJECT
#define TEX_PD_PSYS
#define TEX_INT
#define POINT_DATA_LIFE
#define TEX_PD_FALLOFF_CURVE
@ TEX_PD_COLOR_VERTWEIGHT
@ TEX_PD_COLOR_VERTNOR
@ TEX_PD_COLOR_VERTCOL
@ TEX_PD_COLOR_PARTAGE
@ TEX_PD_COLOR_CONSTANT
@ TEX_PD_COLOR_PARTVEL
@ TEX_PD_COLOR_PARTSPEED
#define TEX_PD_FALLOFF_SMOOTH
#define POINT_DATA_COLOR
#define TEX_PD_FALLOFF_PARTICLE_VEL
#define TEX_PD_FALLOFF_STD
#define TEX_PD_FALLOFF_CONSTANT
#define POINT_DATA_VEL
#define TEX_PD_WORLDSPACE
#define TEX_PD_FALLOFF_SOFT
#define TEX_PD_OBJECTLOC
#define TEX_PD_FALLOFF_ROOT
_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 z
_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 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 y
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
Scene scene
const Depsgraph * depsgraph
uint col
#define sqrtf(x)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static ulong state[N]
static float turb(float x, float y, float z, int oct, int hard, int nb, float ampscale, float freqscale)
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
Definition: rall1d.h:359
#define min(a, b)
Definition: sort.c:51
float vec[8][3]
struct MDeformWeight * dw
unsigned int def_nr
unsigned int v
struct CustomData pdata ldata
struct MVert * mvert
int totvert
struct MLoop * mloop
int totloop
ListBase particlesystem
float loc[3]
float imat[4][4]
unsigned short actdef
float obmat[4][4]
void * data
struct Depsgraph * depsgraph
Definition: BKE_particle.h:87
struct ParticleSystemModifierData * psmd
Definition: BKE_particle.h:91
struct Scene * scene
Definition: BKE_particle.h:88
struct ParticleSystem * psys
Definition: BKE_particle.h:90
struct Object * ob
Definition: BKE_particle.h:89
ChildParticle * child
ParticleData * particles
ParticleSettings * part
struct LatticeDeformData * lattice_deform_data
struct ParticleCacheKey ** childcache
struct ParticleCacheKey ** pathcache
struct CurveMapping * density_curve
char vertex_attribute_name[64]
struct CurveMapping * falloff_curve
struct Object * object
struct ColorBand * coba
int talpha
Definition: RE_texture.h:85
float tb
Definition: RE_texture.h:84
float tin
Definition: RE_texture.h:84
float ta
Definition: RE_texture.h:84
float tr
Definition: RE_texture.h:84
float tg
Definition: RE_texture.h:84
static void sample_dummy_point_density(int resolution, float *values)
void RE_point_density_sample(Depsgraph *depsgraph, PointDensity *pd, const int resolution, float *values)
static void init_pointdensityrangedata(PointDensity *pd, PointDensityRangeData *pdr, float *density, float *vec, float *age, float *col, struct CurveMapping *density_curve, float velscale)
void RE_point_density_fix_linking(void)
static ThreadMutex sample_mutex
static void pointdensity_cache_object(PointDensity *pd, Object *ob)
static void accum_density(void *userdata, int index, const float co[3], float squared_dist)
struct SampleCallbackData SampleCallbackData
static void point_density_sample_func(void *__restrict data_v, const int iter, const TaskParallelTLS *__restrict UNUSED(tls))
struct PointDensityRangeData PointDensityRangeData
static void pointdensity_cache_vertex_weight(PointDensity *pd, Object *ob, Mesh *mesh, float *data_color)
void RE_point_density_minmax(struct Depsgraph *depsgraph, struct PointDensity *pd, float r_min[3], float r_max[3])
static void point_data_pointers(PointDensity *pd, float **r_data_velocity, float **r_data_life, float **r_data_color)
static void particle_system_minmax(Depsgraph *depsgraph, Scene *scene, Object *object, ParticleSystem *psys, float radius, float min[3], float max[3])
static void pointdensity_cache_vertex_color(PointDensity *pd, Object *UNUSED(ob), Mesh *mesh, float *data_color)
static int pointdensity(PointDensity *pd, const float texvec[3], TexResult *texres, float r_vec[3], float *r_age, float r_col[3])
static void pointdensity_cache_psys(Depsgraph *depsgraph, Scene *scene, PointDensity *pd, Object *ob, ParticleSystem *psys)
void RE_point_density_cache(struct Depsgraph *depsgraph, PointDensity *pd)
static void pointdensity_color(PointDensity *pd, TexResult *texres, float age, const float vec[3], const float col[3])
static float density_falloff(PointDensityRangeData *pdr, int index, float squared_dist)
static void alloc_point_data(PointDensity *pd)
static void pointdensity_cache_vertex_normal(PointDensity *pd, Object *UNUSED(ob), Mesh *mesh, float *data_color)
static void cache_pointdensity(Depsgraph *depsgraph, Scene *scene, PointDensity *pd)
void RE_point_density_free(struct PointDensity *pd)
static int point_data_used(PointDensity *pd)
static void free_pointdensity(PointDensity *pd)
float max
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)