=trunk=
[blender-staging.git] / source / blender / render / intern / source / pointdensity.c
index 7ccf81b77555b2a24027eaed8f71e80da9c4d886..d3d3e4d261c3ef5dc6d3076d386924640e12c1da 100644 (file)
@@ -47,6 +47,7 @@
 #include "BKE_particle.h"
 #include "BKE_scene.h"
 #include "BKE_texture.h"
+#include "BKE_colortools.h"
 
 #include "DNA_meshdata_types.h"
 #include "DNA_texture_types.h"
@@ -69,9 +70,9 @@ static int point_data_used(PointDensity *pd)
        int pd_bitflag = 0;
        
        if (pd->source == TEX_PD_PSYS) {
-               if ((pd->noise_influence == TEX_PD_NOISE_VEL) || (pd->color_source == TEX_PD_COLOR_PARTVEL) || (pd->color_source == TEX_PD_COLOR_PARTSPEED))
+               if ((pd->noise_influence == TEX_PD_NOISE_VEL) || (pd->falloff_type == TEX_PD_FALLOFF_PARTICLE_VEL) || (pd->color_source == TEX_PD_COLOR_PARTVEL) || (pd->color_source == TEX_PD_COLOR_PARTSPEED))
                        pd_bitflag |= POINT_DATA_VEL;
-               if ((pd->noise_influence == TEX_PD_NOISE_AGE) || (pd->color_source == TEX_PD_COLOR_PARTAGE)) 
+               if ((pd->noise_influence == TEX_PD_NOISE_AGE) || (pd->color_source == TEX_PD_COLOR_PARTAGE) || (pd->falloff_type == TEX_PD_FALLOFF_PARTICLE_AGE)
                        pd_bitflag |= POINT_DATA_LIFE;
        }
                
@@ -180,6 +181,7 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa
                                }
                                
                                pd->point_data[offset + i] = pa_time;
+                               
                        }
                }
        }
@@ -331,6 +333,8 @@ typedef struct PointDensityRangeData
        float *age;
        int point_data_used;
        int offset;
+       struct CurveMapping *density_curve;
+       float velscale;
 } PointDensityRangeData;
 
 static void accum_density(void *userdata, int index, float squared_dist)
@@ -339,6 +343,15 @@ static void accum_density(void *userdata, int index, float squared_dist)
        const float dist = (pdr->squared_radius - squared_dist) / pdr->squared_radius * 0.5f;
        float density = 0.0f;
        
+       if (pdr->point_data_used & POINT_DATA_VEL) {
+               pdr->vec[0] += pdr->point_data[index*3 + 0]; //* density;
+               pdr->vec[1] += pdr->point_data[index*3 + 1]; //* density;
+               pdr->vec[2] += pdr->point_data[index*3 + 2]; //* density;
+       }
+       if (pdr->point_data_used & POINT_DATA_LIFE) {
+               *pdr->age += pdr->point_data[pdr->offset + index]; // * density;
+       }
+       
        if (pdr->falloff_type == TEX_PD_FALLOFF_STD)
                density = dist;
        else if (pdr->falloff_type == TEX_PD_FALLOFF_SMOOTH)
@@ -349,21 +362,21 @@ static void accum_density(void *userdata, int index, float squared_dist)
                density = pdr->squared_radius;
        else if (pdr->falloff_type == TEX_PD_FALLOFF_ROOT)
                density = sqrt(dist);
+       else if (pdr->falloff_type == TEX_PD_FALLOFF_PARTICLE_AGE)
+               density = dist*MIN2(pdr->point_data[pdr->offset + index], 1.0f);
+       else if (pdr->falloff_type == TEX_PD_FALLOFF_PARTICLE_VEL)
+               density = dist*len_v3(pdr->point_data + index*3)*pdr->velscale;
        
-       if (pdr->point_data_used & POINT_DATA_VEL) {
-               pdr->vec[0] += pdr->point_data[index*3 + 0]; //* density;
-               pdr->vec[1] += pdr->point_data[index*3 + 1]; //* density;
-               pdr->vec[2] += pdr->point_data[index*3 + 2]; //* density;
-       }
-       if (pdr->point_data_used & POINT_DATA_LIFE) {
-               *pdr->age += pdr->point_data[pdr->offset + index]; // * density;
+       if (pdr->density_curve && dist != 0.0f) {
+               density = curvemapping_evaluateF(pdr->density_curve, 0, density/dist)*dist;
        }
        
        *pdr->density += density;
 }
 
 
-static void init_pointdensityrangedata(PointDensity *pd, PointDensityRangeData *pdr, float *density, float *vec, float *age)
+static void init_pointdensityrangedata(PointDensity *pd, PointDensityRangeData *pdr, 
+       float *density, float *vec, float *age, struct CurveMapping *density_curve, float velscale)
 {
        pdr->squared_radius = pd->radius*pd->radius;
        pdr->density = density;
@@ -375,6 +388,8 @@ static void init_pointdensityrangedata(PointDensity *pd, PointDensityRangeData *
        pdr->noise_influence = pd->noise_influence;
        pdr->point_data_used = point_data_used(pd);
        pdr->offset = (pdr->point_data_used & POINT_DATA_VEL)?pd->totpoints*3:0;
+       pdr->density_curve = density_curve;
+       pdr->velscale = velscale;
 }
 
 
@@ -394,7 +409,8 @@ int pointdensitytex(Tex *tex, float *texvec, TexResult *texres)
        if ((!pd) || (!pd->point_tree))         
                return 0;
                
-       init_pointdensityrangedata(pd, &pdr, &density, vec, &age);
+       init_pointdensityrangedata(pd, &pdr, &density, vec, &age, 
+               (pd->flag&TEX_PD_FALLOFF_CURVE ? pd->falloff_curve : NULL), pd->falloff_speed_scale*0.001f);
        noise_fac = pd->noise_fac * 0.5f;       /* better default */
        
        VECCOPY(co, texvec);