diff options
author | Matt Ebb <matt@mke3.net> | 2008-11-09 04:16:12 +0300 |
---|---|---|
committer | Matt Ebb <matt@mke3.net> | 2008-11-09 04:16:12 +0300 |
commit | a972107b03a3b8b00e1548d99e790612dc9f0ccc (patch) | |
tree | 93f8277505c327eb2ae125a177edb5d94807b071 /source | |
parent | f5f0c8fb37eaac8be9efc44b2802fb87fcf85727 (diff) |
Point Density texture: colouring
This introduces a few new ways of modifying the intensity and colour output
generated by the Point Density texture. Previously, the texture only output
intensity information, but now you can map it to colours along a gradient
ramp, based on information coming out of a particle system.
This lets you do things like colour a particle system based on the individual
particles' age - the main reason I need it is to fade particles out over time.
The colorband influences both the colour and intensity (using the colorband's
alpha value), which makes it easy to map a single point density texture to
both intensity values in the Map To panel (such as density or emit) and colour
values (such as absorb col or emit col). This is how the below examples are
set up, an example .blend file is available here:
http://mke3.net/blender/devel/rendering/volumetrics/pd_test4.blend
The different modes:
* Constant
No modifications to intensity or colour (pure white)
* Particle Age
Maps the color ramp along the particles' lifetimes:
http://mke3.net/blender/devel/rendering/volumetrics/pd_mod_partage.mov
* Particle Speed
Maps the color ramp to the particles' absolute speed per frame (in Blender
units). There's an additional scale parameter that you can use to bring this
speed into a 0.0 - 1.0 range, if your particles are travelling too faster or
slower than 0-1.
http://mke3.net/blender/devel/rendering/volumetrics/pd_mod_speed.mov
* Velocity -> RGB
Outputs the particle XYZ velocity vector as RGB colours. This may be useful
for comp work, or maybe in the future things like displacement. Again, there's
a scale parameter to control it.
http://mke3.net/blender/devel/rendering/volumetrics/pd_mod_velrgb.mov
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/texture.c | 6 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 5 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 5 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_texture_types.h | 21 | ||||
-rw-r--r-- | source/blender/render/intern/source/pointdensity.c | 207 | ||||
-rw-r--r-- | source/blender/src/buttons_shading.c | 427 |
6 files changed, 423 insertions, 248 deletions
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 0dbc0228820..76ef6bdb4e8 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -883,7 +883,9 @@ PointDensity *BKE_add_pointdensity(void) pd->noise_depth = 1; pd->noise_fac = 1.0f; pd->noise_influence = TEX_PD_NOISE_STATIC; - + pd->coba = add_colorband(1); + pd->speed_scale = 1.0f; + pd->totpoints = 0; return pd; } @@ -894,6 +896,7 @@ PointDensity *BKE_copy_pointdensity(PointDensity *pd) pdn= MEM_dupallocN(pd); pdn->point_tree = NULL; pdn->point_data = NULL; + if(pdn->coba) pdn->coba= MEM_dupallocN(pdn->coba); return pdn; } @@ -908,6 +911,7 @@ void BKE_free_pointdensitydata(PointDensity *pd) MEM_freeN(pd->point_data); pd->point_data = NULL; } + if(pd->coba) MEM_freeN(pd->coba); } void BKE_free_pointdensity(PointDensity *pd) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 83a66143ffc..372e9856b98 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2506,6 +2506,7 @@ static void direct_link_texture(FileData *fd, Tex *tex) tex->pd= newdataadr(fd, tex->pd); if(tex->pd) { tex->pd->point_tree = NULL; + tex->pd->coba= newdataadr(fd, tex->pd->coba); } tex->preview = direct_link_preview_image(fd, tex->preview); @@ -7902,6 +7903,10 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } if (tex->pd->falloff_softness < 1.0f) tex->pd->falloff_softness = 2.0f; + if (tex->pd->coba == NULL) { + tex->pd->coba = add_colorband(1); + tex->pd->speed_scale = 1.0f; + } } } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 7249090dfa7..5c1032045d7 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1335,7 +1335,10 @@ static void write_textures(WriteData *wd, ListBase *idbase) if(tex->plugin) writestruct(wd, DATA, "PluginTex", 1, tex->plugin); if(tex->coba) writestruct(wd, DATA, "ColorBand", 1, tex->coba); if(tex->env) writestruct(wd, DATA, "EnvMap", 1, tex->env); - if(tex->pd) writestruct(wd, DATA, "PointDensity", 1, tex->pd); + if(tex->pd) { + writestruct(wd, DATA, "PointDensity", 1, tex->pd); + if(tex->pd->coba) writestruct(wd, DATA, "ColorBand", 1, tex->pd->coba); + } write_previews(wd, tex->preview); } diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index c51311bb621..b057efb4a55 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -134,7 +134,10 @@ typedef struct PointDensity { float falloff_softness; float radius; short source; - short pdpad; + short color_source; + int totpoints; + + int pdpad; struct Object *object; /* for 'Object' or 'Particle system' type - source object */ short psys_cache_space; /* cache points in worldspace, object space, ... ? */ @@ -151,7 +154,9 @@ typedef struct PointDensity { short noise_depth; short noise_influence; float noise_fac; - float pdpad4; + + float speed_scale; + struct ColorBand *coba; /* for time -> color */ } PointDensity; @@ -442,7 +447,17 @@ typedef struct TexMapping { /* noise_influence */ #define TEX_PD_NOISE_STATIC 0 #define TEX_PD_NOISE_VEL 1 -#define TEX_PD_NOISE_TIME 2 +#define TEX_PD_NOISE_AGE 2 +#define TEX_PD_NOISE_TIME 3 + +/* color_source */ +#define TEX_PD_COLOR_CONSTANT 0 +#define TEX_PD_COLOR_PARTAGE 1 +#define TEX_PD_COLOR_PARTSPEED 2 +#define TEX_PD_COLOR_PARTVEL 3 + +#define POINT_DATA_VEL 1 +#define POINT_DATA_LIFE 2 #endif diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index c80ee767142..db3e57e0b79 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -39,6 +39,7 @@ #include "BKE_main.h" #include "BKE_object.h" #include "BKE_particle.h" +#include "BKE_texture.h" #include "DNA_texture_types.h" #include "DNA_particle_types.h" @@ -47,16 +48,59 @@ #include "renderdatabase.h" #include "texture.h" +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ +/* only to be used here in this file, it's for speed */ +extern struct Render R; +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + + +static int point_data_used(PointDensity *pd) +{ + int pd_bitflag = 0; + + if ((pd->noise_influence == TEX_PD_NOISE_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)) + pd_bitflag |= POINT_DATA_LIFE; + + return pd_bitflag; +} + + +/* additional data stored alongside the point density BVH, + * accessible by point index number to retrieve other information + * such as particle velocity or lifetime */ +static void make_point_data(PointDensity *pd, int total_particles, int point_data_used) +{ + int data_size = 0; + + if (point_data_used & POINT_DATA_VEL) { + /* store 3 channels of velocity data */ + data_size += 3; + } + if (point_data_used & POINT_DATA_LIFE) { + /* store 1 channel of lifetime data */ + data_size += 1; + } + + if (data_size) + pd->point_data = MEM_mallocN(sizeof(float)*data_size*total_particles, "particle point data"); +} + static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, ParticleSystem *psys) { DerivedMesh* dm; ParticleKey state; + ParticleData *pa=NULL; float cfra=bsystem_time(ob,(float)G.scene->r.cfra,0.0); int i, childexists; - int total_particles; + int total_particles, offset=0; + int data_used = point_data_used(pd); float partco[3]; float obview[4][4]; + /* init everything */ if (!psys || !ob || !pd) return; @@ -79,16 +123,14 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa psys->lattice=psys_get_lattice(ob,psys); pd->point_tree = BLI_bvhtree_new(total_particles, 0.0, 4, 6); - - if (pd->noise_influence == TEX_PD_NOISE_VEL) - pd->point_data = MEM_mallocN(sizeof(float)*3*total_particles, "velocity point data"); - else if (pd->noise_influence == TEX_PD_NOISE_TIME) - pd->point_data = MEM_mallocN(sizeof(float)*total_particles, "time point data"); + make_point_data(pd, total_particles, data_used); + pd->totpoints = total_particles; + if (data_used & POINT_DATA_VEL) offset = pd->totpoints*3; if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT)) childexists = 1; - for (i = 0; i < total_particles; i++) { + for (i=0, pa=psys->particles; i < total_particles; i++, pa++) { state.time = cfra; if(psys_get_particle_state(ob, psys, i, &state, 0)) { @@ -107,12 +149,14 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa BLI_bvhtree_insert(pd->point_tree, i, partco, 1); - if (pd->noise_influence == TEX_PD_NOISE_VEL) { + if (data_used & POINT_DATA_VEL) { pd->point_data[i*3 + 0] = state.vel[0]; pd->point_data[i*3 + 1] = state.vel[1]; pd->point_data[i*3 + 2] = state.vel[2]; - } else if (pd->noise_influence == TEX_PD_NOISE_TIME) { - pd->point_data[i] = state.time; + } + if (data_used & POINT_DATA_LIFE) { + float pa_time = (cfra - pa->time)/pa->lifetime; + pd->point_data[offset + i] = pa_time; } } } @@ -140,6 +184,7 @@ static void pointdensity_cache_object(Render *re, PointDensity *pd, ObjectRen *o Mat4Invert(obr->ob->imat, obr->ob->obmat); pd->point_tree = BLI_bvhtree_new(obr->totvert, 0.0, 4, 6); + pd->totpoints = obr->totvert; for(i=0; i<obr->totvert; i++) { float ver_co[3]; @@ -216,6 +261,7 @@ static void free_pointdensity(Render *re, Tex *tex) MEM_freeN(pd->point_data); pd->point_data = NULL; } + pd->totpoints = 0; } @@ -263,7 +309,9 @@ typedef struct PointDensityRangeData float softness; short falloff_type; short noise_influence; - float *time; + float *age; + int point_data_used; + int offset; } PointDensityRangeData; void accum_density(void *userdata, int index, float squared_dist) @@ -283,83 +331,130 @@ void accum_density(void *userdata, int index, float squared_dist) else if (pdr->falloff_type == TEX_PD_FALLOFF_ROOT) density = sqrt(dist); - if (pdr->point_data) { - if (pdr->noise_influence == TEX_PD_NOISE_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; - } else if (pdr->noise_influence == TEX_PD_NOISE_TIME) { - *pdr->time += pdr->point_data[index]; // * density; - } - } + 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; + } *pdr->density += density; } -#define MAX_POINTS_NEAREST 25 + +static void init_pointdensityrangedata(PointDensity *pd, PointDensityRangeData *pdr, float *density, float *vec, float *age) +{ + pdr->squared_radius = pd->radius*pd->radius; + pdr->density = density; + pdr->point_data = pd->point_data; + pdr->falloff_type = pd->falloff_type; + pdr->vec = vec; + pdr->age = age; + pdr->softness = pd->falloff_softness; + 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; +} + + int pointdensitytex(Tex *tex, float *texvec, TexResult *texres) { - int retval = TEX_INT; + int retval = TEX_INT+TEX_RGB; PointDensity *pd = tex->pd; PointDensityRangeData pdr; - float density=0.0f, time=0.0f; - float vec[3] = {0.0, 0.0, 0.0}; - float co[3]; + float density=0.0f, age=0.0f, time=0.0f; + float vec[3] = {0.0f, 0.0f, 0.0f}, co[3]; + float col[4]; float turb, noise_fac; - int num; + int num=0; if ((!pd) || (!pd->point_tree)) { texres->tin = 0.0f; return 0; } - pdr.squared_radius = pd->radius*pd->radius; - pdr.density = &density; - pdr.point_data = pd->point_data; - pdr.falloff_type = pd->falloff_type; - pdr.vec = vec; - pdr.time = &time; - pdr.softness = pd->falloff_softness; - pdr.noise_influence = pd->noise_influence; + init_pointdensityrangedata(pd, &pdr, &density, vec, &age); noise_fac = pd->noise_fac * 0.5f; /* better default */ VECCOPY(co, texvec); + if (point_data_used(pd)) { + /* does a BVH lookup to find accumulated density and additional point data * + * stores particle velocity vector in 'vec', and particle lifetime in 'time' */ + num = BLI_bvhtree_range_query(pd->point_tree, co, pd->radius, accum_density, &pdr); + if (num > 0) { + age /= num; + VecMulf(vec, 1.0f/num); + } + } + if (pd->flag & TEX_PD_TURBULENCE) { - retval |= TEX_RGB; - - if (ELEM(pd->noise_influence, TEX_PD_NOISE_VEL, TEX_PD_NOISE_TIME)) { - /* find the average speed vectors or particle time, - * for perturbing final density lookup with */ - num = BLI_bvhtree_range_query(pd->point_tree, co, pd->radius, accum_density, &pdr); - density = 0.0f; - - if (pd->noise_influence == TEX_PD_NOISE_TIME) { - vec[0] = vec[1] = vec[2] = time/num; - //if ((G.rt==1) && (time > 0.f)) printf("time: %f time/num: %f \n", time, time/num); - } - - Normalize(vec); + + if (pd->noise_influence == TEX_PD_NOISE_AGE) { + turb = BLI_turbulence(pd->noise_size, texvec[0]+age, texvec[1]+age, texvec[2]+age, pd->noise_depth); } - - turb = BLI_turbulence(pd->noise_size, texvec[0]+vec[0], texvec[1]+vec[1], texvec[2]+vec[2], pd->noise_depth); + else if (pd->noise_influence == TEX_PD_NOISE_TIME) { + time = R.cfra / (float)R.r.efra; + turb = BLI_turbulence(pd->noise_size, texvec[0]+time, texvec[1]+time, texvec[2]+time, pd->noise_depth); + } + else { + turb = BLI_turbulence(pd->noise_size, texvec[0]+vec[0], texvec[1]+vec[1], texvec[2]+vec[2], pd->noise_depth); + } + turb -= 0.5f; /* re-center 0.0-1.0 range around 0 to prevent offsetting result */ /* now we have an offset coordinate to use for the density lookup */ co[0] = texvec[0] + noise_fac * turb; co[1] = texvec[1] + noise_fac * turb; co[2] = texvec[2] + noise_fac * turb; + + /* reset and do a new BVH query with the perturbed coordinates */ + density = vec[0] = vec[1] = vec[2] = 0.0f; + num = BLI_bvhtree_range_query(pd->point_tree, co, pd->radius, accum_density, &pdr); + if (num > 0) { + age /= num; + VecMulf(vec, 1.0f/num); + } + } - BLI_bvhtree_range_query(pd->point_tree, co, pd->radius, accum_density, &pdr); - texres->tin = density; BRICONT; - texres->tr = vec[0]; - texres->tg = vec[1]; - texres->tb = vec[2]; - //texres->ta = density; + switch (pd->color_source) { + case TEX_PD_COLOR_PARTAGE: + if (pd->coba) { + if (do_colorband(pd->coba, age, col)) { + texres->talpha= 1; + QUATCOPY(&texres->tr, col); + texres->tin *= texres->ta; + } + } + break; + case TEX_PD_COLOR_PARTSPEED: + { + float speed = VecLength(vec) * pd->speed_scale; + + if (pd->coba) { + if (do_colorband(pd->coba, speed, col)) { + texres->talpha= 1; + QUATCOPY(&texres->tr, col); + texres->tin *= texres->ta; + } + } + break; + } + case TEX_PD_COLOR_PARTVEL: + VecMulf(vec, pd->speed_scale); + VECCOPY(&texres->tr, vec); + texres->ta = 1.0f; + break; + default: + texres->tr = texres->tg = texres->tb = texres->ta = 1.0f; + break; + } BRICONTRGB; return retval; diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index dbe3db871b4..b9ea4ebe9d6 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -427,6 +427,115 @@ void do_texbuts(unsigned short event) } } +static void colorband_pos_cb(void *coba_v, void *unused_v) +{ + ColorBand *coba= coba_v; + int a; + + if(coba->tot<2) return; + + for(a=0; a<coba->tot; a++) coba->data[a].cur= a; + qsort(coba->data, coba->tot, sizeof(CBData), vergcband); + for(a=0; a<coba->tot; a++) { + if(coba->data[a].cur==coba->cur) { + if(coba->cur!=a) addqueue(curarea->win, REDRAW, 0); /* button cur */ + coba->cur= a; + break; + } + } +} + +static void colorband_add_cb(void *coba_v, void *unused_v) +{ + ColorBand *coba= coba_v; + + if(coba->tot < MAXCOLORBAND-1) coba->tot++; + coba->cur= coba->tot-1; + + colorband_pos_cb(coba, NULL); + BIF_undo_push("Add colorband"); + +} + +static void colorband_del_cb(void *coba_v, void *unused_v) +{ + ColorBand *coba= coba_v; + int a; + + if(coba->tot<2) return; + + for(a=coba->cur; a<coba->tot; a++) { + coba->data[a]= coba->data[a+1]; + } + if(coba->cur) coba->cur--; + coba->tot--; + + BIF_undo_push("Delete colorband"); + BIF_preview_changed(ID_TE); +} + + +/* offset aligns from bottom, standard width 300, height 115 */ +static void draw_colorband_buts(uiBlock *block, ColorBand *coba, int xoffs, int yoffs, int redraw) +{ + CBData *cbd; + uiBut *bt; + + if(coba==NULL) return; + + bt= uiDefBut(block, BUT, redraw, "Add", 80+xoffs,95+yoffs,37,20, 0, 0, 0, 0, 0, "Adds a new color position to the colorband"); + uiButSetFunc(bt, colorband_add_cb, coba, NULL); + uiDefButS(block, NUM, redraw, "Cur:", 117+xoffs,95+yoffs,81,20, &coba->cur, 0.0, (float)(coba->tot-1), 0, 0, "Displays the active color from the colorband"); + bt= uiDefBut(block, BUT, redraw, "Del", 199+xoffs,95+yoffs,37,20, 0, 0, 0, 0, 0, "Deletes the active position"); + uiButSetFunc(bt, colorband_del_cb, coba, NULL); + uiDefButS(block, ROW, redraw, "E", 236+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 1.0, 0, 0, "Sets interpolation type 'Ease' (quadratic) "); + uiDefButS(block, ROW, redraw, "C", 252+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 3.0, 0, 0, "Sets interpolation type Cardinal"); + uiDefButS(block, ROW, redraw, "L", 268+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 0.0, 0, 0, "Sets interpolation type Linear"); + uiDefButS(block, ROW, redraw, "S", 284+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 2.0, 0, 0, "Sets interpolation type B-Spline"); + + uiDefBut(block, BUT_COLORBAND, redraw, "", xoffs,65+yoffs,300,30, coba, 0, 0, 0, 0, ""); + + cbd= coba->data + coba->cur; + + uiBlockBeginAlign(block); + bt= uiDefButF(block, NUM, redraw, "Pos", xoffs,40+yoffs,110,20, &cbd->pos, 0.0, 1.0, 10, 0, "Sets the position of the active color"); + uiButSetFunc(bt, colorband_pos_cb, coba, NULL); + uiDefButF(block, COL, redraw, "", xoffs,20+yoffs,110,20, &(cbd->r), 0, 0, 0, B_BANDCOL, ""); + uiDefButF(block, NUMSLI, redraw, "A ", xoffs,yoffs,110,20, &cbd->a, 0.0, 1.0, 10, 0, "Sets the alpha value for this position"); + + uiBlockBeginAlign(block); + uiDefButF(block, NUMSLI, redraw, "R ", 115+xoffs,40+yoffs,185,20, &cbd->r, 0.0, 1.0, B_BANDCOL, 0, "Sets the red value for the active color"); + uiDefButF(block, NUMSLI, redraw, "G ", 115+xoffs,20+yoffs,185,20, &cbd->g, 0.0, 1.0, B_BANDCOL, 0, "Sets the green value for the active color"); + uiDefButF(block, NUMSLI, redraw, "B ", 115+xoffs,yoffs,185,20, &cbd->b, 0.0, 1.0, B_BANDCOL, 0, "Sets the blue value for the active color"); + uiBlockEndAlign(block); +} + +void draw_colorband_buts_small(uiBlock *block, ColorBand *coba, rctf *butr, int event) +{ + CBData *cbd; + uiBut *bt; + float unit= (butr->xmax-butr->xmin)/14.0f; + float xs= butr->xmin; + + cbd= coba->data + coba->cur; + + uiBlockBeginAlign(block); + uiDefButF(block, COL, event, "", xs,butr->ymin+20.0f,2.0f*unit,20, &(cbd->r), 0, 0, 0, B_BANDCOL, ""); + uiDefButF(block, NUM, event, "A:", xs+2.0f*unit,butr->ymin+20.0f,4.0f*unit,20, &(cbd->a), 0.0f, 1.0f, 10, 2, ""); + bt= uiDefBut(block, BUT, event, "Add", xs+6.0f*unit,butr->ymin+20.0f,2.0f*unit,20, NULL, 0, 0, 0, 0, "Adds a new color position to the colorband"); + uiButSetFunc(bt, colorband_add_cb, coba, NULL); + bt= uiDefBut(block, BUT, event, "Del", xs+8.0f*unit,butr->ymin+20.0f,2.0f*unit,20, NULL, 0, 0, 0, 0, "Deletes the active position"); + uiButSetFunc(bt, colorband_del_cb, coba, NULL); + uiDefButS(block, ROW, event, "E", xs+10.0f*unit,butr->ymin+20.0f,unit,20, &coba->ipotype, 5.0, 1.0, 0, 0, "Sets interpolation type 'Ease' (quadratic) "); + uiDefButS(block, ROW, event, "C", xs+11.0f*unit,butr->ymin+20.0f,unit,20, &coba->ipotype, 5.0, 3.0, 0, 0, "Sets interpolation type Cardinal"); + uiDefButS(block, ROW, event, "L", xs+12.0f*unit,butr->ymin+20.0f,unit,20, &coba->ipotype, 5.0, 0.0, 0, 0, "Sets interpolation type Linear"); + uiDefButS(block, ROW, event, "S", xs+13.0f*unit,butr->ymin+20.0f,unit,20, &coba->ipotype, 5.0, 2.0, 0, 0, "Sets interpolation type B-Spline"); + + uiDefBut(block, BUT_COLORBAND, event, "", xs,butr->ymin,butr->xmax-butr->xmin,20.0f, coba, 0, 0, 0, 0, ""); + uiBlockEndAlign(block); + +} + static void texture_panel_plugin(Tex *tex) { uiBlock *block; @@ -731,109 +840,161 @@ static void texture_panel_voronoi(Tex *tex) uiDefButF(block, NUMSLI, B_TEXPRV, "W4: ", 10, 10, 150, 19, &tex->vn_w4, -2.0, 2.0, 10, 0, "Sets feature weight 4"); } -static void texture_panel_pointdensity(Tex *tex) +static void texture_panel_pointdensity_modify(Tex *tex) { uiBlock *block; PointDensity *pd; - short yco=PANEL_YMAX; + short yco=PANEL_YMAX, ymid; - block= uiNewBlock(&curarea->uiblocks, "texture_panel_pointdensity", UI_EMBOSS, UI_HELV, curarea->win); - if(uiNewPanel(curarea, block, "Point Density", "Texture", PANELX, PANELY, PANELW, PANELH+25)==0) return; + block= uiNewBlock(&curarea->uiblocks, "texture_panel_pointdensity_modify", UI_EMBOSS, UI_HELV, curarea->win); + if(uiNewPanel(curarea, block, "Modifiers", "Texture", PANELX, PANELY, PANELW, PANELH+20)==0) return; uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE); - + if(tex->pd==NULL) { tex->pd= BKE_add_pointdensity(); - tex->pd->object= OBACT; } - if(tex->pd) { - pd= tex->pd; - - uiDefBut(block, LABEL, B_NOP, "Density estimation:", + if(!tex->pd) return; + + if (pd->source == TEX_PD_PSYS) { + uiDefBut(block, LABEL, B_NOP, "Color & Intensity By:", X2CLM1, yco-=BUTH, BUTW2, BUTH, 0, 0, 0, 0, 0, ""); - uiDefButF(block, NUM, B_REDR, "Radius: ", - X2CLM1, yco-=BUTH, BUTW2, BUTH, &(pd->radius), 0.001, 100.0, 10, 2, "Radius to look for nearby particles within"); - - yco -= YSPACE; - - uiDefBut(block, LABEL, B_NOP, "Falloff:", - X2CLM1, yco-=BUTH, BUTW2, BUTH, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); - uiDefButS(block, MENU, B_REDR, "Standard %x0|Smooth %x1|Soft %x2|Constant %x3|Root %x4", - X2CLM1, yco-=BUTH, BUTW2, BUTH, &pd->falloff_type, 0.0, 0.0, 0, 0, "Falloff type"); - if (pd->falloff_type == TEX_PD_FALLOFF_SOFT) { - uiDefButF(block, NUM, B_REDR, "Softness: ", - X2CLM1, yco-=BUTH, BUTW2, BUTH, &(pd->falloff_softness), 1.0, 1024.0, 10, 2, "The intensity of the falloff"); + uiDefButS(block, MENU, B_TEXREDR_PRV, "Constant %x0|Particle Age %x1|Particle Speed %x2|Velocity -> RGB %x3|", + X2CLM1, yco-=BUTH, BUTW2, BUTH, &pd->color_source, 0.0, 0.0, 0, 0, "Particle Life: Lifetime mapped as 0.0 - 1.0 intensity, Velocity: XYZ velocity mapped as RGB colours"); + if (ELEM(pd->color_source, TEX_PD_COLOR_PARTSPEED, TEX_PD_COLOR_PARTVEL)) { + uiDefButF(block, NUM, B_REDR, "Scale: ", + X2CLM1, yco-=BUTH, BUTW2, BUTH, &(pd->speed_scale), 0.001, 100.0, 10, 2, "Multipler to bring particle speed within an acceptable range"); } uiBlockEndAlign(block); - yco -= YSPACE; + yco-= 2*BUTH; + if (ELEM(pd->color_source, TEX_PD_COLOR_PARTAGE, TEX_PD_COLOR_PARTSPEED)) { + rctf rect = {X2CLM1, X2CLM1+BUTW1, yco, yco}; + if (tex->pd->coba == NULL) tex->pd->coba = add_colorband(1); + draw_colorband_buts_small(block, tex->pd->coba, &rect, B_TEXREDR_PRV); + } else { + /* spacer */ + uiDefBut(block, LABEL, B_NOP, "", + X2CLM2, yco, BUTW2, BUTH*2, 0, 0, 0, 0, 0, ""); + } - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, TEX_PD_TURBULENCE, B_REDR, "Turbulence", - X2CLM1, yco-=BUTH, BUTW2, BUTH, &(pd->flag), 0, 0, 0, 0, "Add directed turbulence to the density estimation"); - - if (pd->flag & TEX_PD_TURBULENCE) { - - uiDefButF(block, NUM, B_REDR, "Size: ", - X2CLM1, yco-=BUTH, BUTW2, BUTH, &(pd->noise_size), 0.001, 100.0, 10, 2, "Turbulence size"); - uiDefButS(block, NUM, B_REDR, "Depth: ", - X2CLM1, yco-=BUTH, BUTW2, BUTH, &(pd->noise_depth), 0.0, 100.0, 10, 2, "Turbulence depth"); - uiDefButF(block, NUM, B_REDR, "Strength: ", - X2CLM1, yco-=BUTH, BUTW2, BUTH, &(pd->noise_fac), 0.001, 100.0, 10, 2, ""); - - uiBlockEndAlign(block); + if (!ELEM(pd->color_source, TEX_PD_COLOR_PARTSPEED, TEX_PD_COLOR_PARTVEL)) yco -= BUTH; + } + + ymid = yco -= YSPACE; + + uiDefButBitS(block, TOG, TEX_PD_TURBULENCE, B_REDR, "Turbulence", + X2CLM1, yco-=BUTH, BUTW2, BUTH, &(pd->flag), 0, 0, 0, 0, "Add directed turbulence to the density estimation"); + + yco -= YSPACE; + + uiBlockBeginAlign(block); + if (pd->flag & TEX_PD_TURBULENCE) { + + uiDefButF(block, NUM, B_REDR, "Size: ", + X2CLM1, yco-=BUTH, BUTW2, BUTH, &(pd->noise_size), 0.001, 100.0, 10, 2, "Turbulence size"); + uiDefButS(block, NUM, B_REDR, "Depth: ", + X2CLM1, yco-=BUTH, BUTW2, BUTH, &(pd->noise_depth), 0.0, 100.0, 10, 2, "Turbulence depth"); + uiDefButF(block, NUM, B_REDR, "Strength: ", + X2CLM1, yco-=BUTH, BUTW2, BUTH, &(pd->noise_fac), 0.001, 100.0, 10, 2, ""); + + uiBlockEndAlign(block); + + yco = ymid - BUTH - YSPACE; + + uiDefBut(block, LABEL, B_NOP, "Noise Influence:", + X2CLM2, yco-=BUTH, BUTW2, BUTH, 0, 0, 0, 0, 0, ""); - yco -= YSPACE; + if (pd->source == TEX_PD_PSYS) { + uiDefButS(block, MENU, B_REDR, "Noise Influence %t|Static %x0|Velocity %x1|Particle Age %x2|Time %x3", + X2CLM2, yco-=BUTH, BUTW2, BUTH, &(pd->noise_influence), 0.0, 0.0, 0, 0, "Noise Influence"); + } else if (pd->source == TEX_PD_OBJECT) { + uiDefButS(block, MENU, B_REDR, "Noise Influence %t|Static %x0|Time %x3", + X2CLM2, yco-=BUTH, BUTW2, BUTH, &(pd->noise_influence), 0.0, 0.0, 0, 0, "Noise Influence"); + } + } else { + uiDefBut(block, LABEL, B_NOP, "", + X2CLM2, yco-=2*BUTH, BUTW2, BUTH, 0, 0, 0, 0, 0, ""); + } - if (pd->source == TEX_PD_PSYS) { - uiDefButS(block, MENU, B_REDR, "Noise Influence %t|Static %x0|Velocity %x1|Time %x2", - X2CLM1, yco-=BUTH, BUTW2, BUTH, &(pd->noise_influence), 0.0, 0.0, 0, 0, "Noise Influence"); - } +} + +static void texture_panel_pointdensity(Tex *tex) +{ + uiBlock *block; + PointDensity *pd; + short yco=PANEL_YMAX; + + block= uiNewBlock(&curarea->uiblocks, "texture_panel_pointdensity", UI_EMBOSS, UI_HELV, curarea->win); + if(uiNewPanel(curarea, block, "Point Density", "Texture", PANELX, PANELY, PANELW, PANELH)==0) return; + uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE); + + if(tex->pd==NULL) { + tex->pd= BKE_add_pointdensity(); + tex->pd->object= OBACT; + } + if(!tex->pd) return; + pd= tex->pd; + + uiDefBut(block, LABEL, B_NOP, "Density estimation:", + X2CLM1, yco-=BUTH, BUTW2, BUTH, 0, 0, 0, 0, 0, ""); + + uiDefButF(block, NUM, B_REDR, "Radius: ", + X2CLM1, yco-=BUTH, BUTW2, BUTH, &(pd->radius), 0.001, 100.0, 10, 2, "Radius to look for nearby particles within"); + + yco -= YSPACE; + + uiDefBut(block, LABEL, B_NOP, "Falloff:", + X2CLM1, yco-=BUTH, BUTW2, BUTH, 0, 0, 0, 0, 0, ""); + uiBlockBeginAlign(block); + uiDefButS(block, MENU, B_REDR, "Standard %x0|Smooth %x1|Soft %x2|Constant %x3|Root %x4", + X2CLM1, yco-=BUTH, BUTW2, BUTH, &pd->falloff_type, 0.0, 0.0, 0, 0, "Falloff type"); + if (pd->falloff_type == TEX_PD_FALLOFF_SOFT) { + uiDefButF(block, NUM, B_REDR, "Softness: ", + X2CLM1, yco-=BUTH, BUTW2, BUTH, &(pd->falloff_softness), 1.0, 1024.0, 10, 2, "The intensity of the falloff"); + } + uiBlockEndAlign(block); + + yco = PANEL_YMAX; + + uiDefBut(block, LABEL, B_NOP, "Point data source:", + X2CLM2, yco-=BUTH, BUTW2, BUTH, 0, 0, 0, 0, 0, ""); + + uiDefButS(block, MENU, B_TEXREDR_PRV, "Particle System %x0|Object Vertices %x1", + X2CLM2, yco-=BUTH, BUTW2, BUTH, &pd->source, 0.0, 0.0, 0, 0, "Source"); + + yco -= YSPACE; + + if (pd->source == TEX_PD_PSYS) { + uiBlockBeginAlign(block); + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_REDR, "Ob:", + X2CLM2, yco-=BUTH, BUTW2, BUTH, &(pd->object), "Object that has the particle system"); + + if (pd->object && pd->object->particlesystem.first) { + uiDefButS(block, NUM, B_REDR, "PSys:", + X2CLM2, yco-=BUTH, BUTW2, BUTH, &(pd->psysindex), 1, 10, 10, 3, "Particle system number in the object"); } uiBlockEndAlign(block); - - yco = PANEL_YMAX; - uiDefBut(block, LABEL, B_NOP, "Point data source:", - X2CLM2, yco-=BUTH, BUTW2, BUTH, 0, 0, 0, 0, 0, ""); + yco -= YSPACE; - uiDefButS(block, MENU, B_TEXREDR_PRV, "Particle System %x0|Object Vertices %x1", - X2CLM2, yco-=BUTH, BUTW2, BUTH, &pd->source, 0.0, 0.0, 0, 0, "Source"); + uiDefBut(block, LABEL, B_NOP, "Cache particles in:", + X2CLM2, yco-=BUTH, BUTW2, BUTH, 0, 0, 0, 0, 0, ""); + uiDefButS(block, MENU, B_TEXREDR_PRV, "Emit Object Location %x0|Emit Object Space %x1|Global Space %x2", + X2CLM2, yco-=BUTH, BUTW2, BUTH, &pd->psys_cache_space, 0.0, 0.0, 0, 0, "Co-ordinate system to cache particles in"); + } + else if (pd->source == TEX_PD_OBJECT) { + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_REDR, "Ob:", + X2CLM2, yco-=BUTH, BUTW2, BUTH, &(pd->object), "Object to render as points"); yco -= YSPACE; - if (pd->source == TEX_PD_PSYS) { - uiBlockBeginAlign(block); - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_REDR, "Ob:", - X2CLM2, yco-=BUTH, BUTW2, BUTH, &(pd->object), "Object that has the particle system"); - - if (pd->object && pd->object->particlesystem.first) { - uiDefButS(block, NUM, B_REDR, "PSys:", - X2CLM2, yco-=BUTH, BUTW2, BUTH, &(pd->psysindex), 1, 10, 10, 3, "Particle system number in the object"); - } - uiBlockEndAlign(block); - - yco -= YSPACE; - - uiDefBut(block, LABEL, B_NOP, "Cache particles in:", - X2CLM2, yco-=BUTH, BUTW2, BUTH, 0, 0, 0, 0, 0, ""); - uiDefButS(block, MENU, B_TEXREDR_PRV, "Emit Object Location %x0|Emit Object Space %x1|Global Space %x2", - X2CLM2, yco-=BUTH, BUTW2, BUTH, &pd->psys_cache_space, 0.0, 0.0, 0, 0, "Co-ordinate system to cache particles in"); - - } - else if (pd->source == TEX_PD_OBJECT) { - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_REDR, "Ob:", - X2CLM2, yco-=BUTH, BUTW2, BUTH, &(pd->object), "Object to render as points"); - - yco -= YSPACE; - - uiDefBut(block, LABEL, B_NOP, "Cache vertices in:", - X2CLM2, yco-=BUTH, BUTW2, BUTH, 0, 0, 0, 0, 0, ""); - uiDefButS(block, MENU, B_TEXREDR_PRV, "Object Location %x0|Object Space %x1|Global Space %x2", - X2CLM2, yco-=BUTH, BUTW2, BUTH, &pd->ob_cache_space, 0.0, 0.0, 0, 0, "Co-ordinate system to cache vertices in"); - } + uiDefBut(block, LABEL, B_NOP, "Cache vertices in:", + X2CLM2, yco-=BUTH, BUTW2, BUTH, 0, 0, 0, 0, 0, ""); + uiDefButS(block, MENU, B_TEXREDR_PRV, "Object Location %x0|Object Space %x1|Global Space %x2", + X2CLM2, yco-=BUTH, BUTW2, BUTH, &pd->ob_cache_space, 0.0, 0.0, 0, 0, "Co-ordinate system to cache vertices in"); } } @@ -1514,115 +1675,6 @@ static void texture_panel_envmap(Tex *tex) } } -static void colorband_pos_cb(void *coba_v, void *unused_v) -{ - ColorBand *coba= coba_v; - int a; - - if(coba->tot<2) return; - - for(a=0; a<coba->tot; a++) coba->data[a].cur= a; - qsort(coba->data, coba->tot, sizeof(CBData), vergcband); - for(a=0; a<coba->tot; a++) { - if(coba->data[a].cur==coba->cur) { - if(coba->cur!=a) addqueue(curarea->win, REDRAW, 0); /* button cur */ - coba->cur= a; - break; - } - } -} - -static void colorband_add_cb(void *coba_v, void *unused_v) -{ - ColorBand *coba= coba_v; - - if(coba->tot < MAXCOLORBAND-1) coba->tot++; - coba->cur= coba->tot-1; - - colorband_pos_cb(coba, NULL); - BIF_undo_push("Add colorband"); - -} - -static void colorband_del_cb(void *coba_v, void *unused_v) -{ - ColorBand *coba= coba_v; - int a; - - if(coba->tot<2) return; - - for(a=coba->cur; a<coba->tot; a++) { - coba->data[a]= coba->data[a+1]; - } - if(coba->cur) coba->cur--; - coba->tot--; - - BIF_undo_push("Delete colorband"); - BIF_preview_changed(ID_TE); -} - - -/* offset aligns from bottom, standard width 300, height 115 */ -static void draw_colorband_buts(uiBlock *block, ColorBand *coba, int xoffs, int yoffs, int redraw) -{ - CBData *cbd; - uiBut *bt; - - if(coba==NULL) return; - - bt= uiDefBut(block, BUT, redraw, "Add", 80+xoffs,95+yoffs,37,20, 0, 0, 0, 0, 0, "Adds a new color position to the colorband"); - uiButSetFunc(bt, colorband_add_cb, coba, NULL); - uiDefButS(block, NUM, redraw, "Cur:", 117+xoffs,95+yoffs,81,20, &coba->cur, 0.0, (float)(coba->tot-1), 0, 0, "Displays the active color from the colorband"); - bt= uiDefBut(block, BUT, redraw, "Del", 199+xoffs,95+yoffs,37,20, 0, 0, 0, 0, 0, "Deletes the active position"); - uiButSetFunc(bt, colorband_del_cb, coba, NULL); - uiDefButS(block, ROW, redraw, "E", 236+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 1.0, 0, 0, "Sets interpolation type 'Ease' (quadratic) "); - uiDefButS(block, ROW, redraw, "C", 252+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 3.0, 0, 0, "Sets interpolation type Cardinal"); - uiDefButS(block, ROW, redraw, "L", 268+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 0.0, 0, 0, "Sets interpolation type Linear"); - uiDefButS(block, ROW, redraw, "S", 284+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 2.0, 0, 0, "Sets interpolation type B-Spline"); - - uiDefBut(block, BUT_COLORBAND, redraw, "", xoffs,65+yoffs,300,30, coba, 0, 0, 0, 0, ""); - - cbd= coba->data + coba->cur; - - uiBlockBeginAlign(block); - bt= uiDefButF(block, NUM, redraw, "Pos", xoffs,40+yoffs,110,20, &cbd->pos, 0.0, 1.0, 10, 0, "Sets the position of the active color"); - uiButSetFunc(bt, colorband_pos_cb, coba, NULL); - uiDefButF(block, COL, redraw, "", xoffs,20+yoffs,110,20, &(cbd->r), 0, 0, 0, B_BANDCOL, ""); - uiDefButF(block, NUMSLI, redraw, "A ", xoffs,yoffs,110,20, &cbd->a, 0.0, 1.0, 10, 0, "Sets the alpha value for this position"); - - uiBlockBeginAlign(block); - uiDefButF(block, NUMSLI, redraw, "R ", 115+xoffs,40+yoffs,185,20, &cbd->r, 0.0, 1.0, B_BANDCOL, 0, "Sets the red value for the active color"); - uiDefButF(block, NUMSLI, redraw, "G ", 115+xoffs,20+yoffs,185,20, &cbd->g, 0.0, 1.0, B_BANDCOL, 0, "Sets the green value for the active color"); - uiDefButF(block, NUMSLI, redraw, "B ", 115+xoffs,yoffs,185,20, &cbd->b, 0.0, 1.0, B_BANDCOL, 0, "Sets the blue value for the active color"); - uiBlockEndAlign(block); -} - -void draw_colorband_buts_small(uiBlock *block, ColorBand *coba, rctf *butr, int event) -{ - CBData *cbd; - uiBut *bt; - float unit= (butr->xmax-butr->xmin)/14.0f; - float xs= butr->xmin; - - cbd= coba->data + coba->cur; - - uiBlockBeginAlign(block); - uiDefButF(block, COL, event, "", xs,butr->ymin+20.0f,2.0f*unit,20, &(cbd->r), 0, 0, 0, B_BANDCOL, ""); - uiDefButF(block, NUM, event, "A:", xs+2.0f*unit,butr->ymin+20.0f,4.0f*unit,20, &(cbd->a), 0.0f, 1.0f, 10, 2, ""); - bt= uiDefBut(block, BUT, event, "Add", xs+6.0f*unit,butr->ymin+20.0f,2.0f*unit,20, NULL, 0, 0, 0, 0, "Adds a new color position to the colorband"); - uiButSetFunc(bt, colorband_add_cb, coba, NULL); - bt= uiDefBut(block, BUT, event, "Del", xs+8.0f*unit,butr->ymin+20.0f,2.0f*unit,20, NULL, 0, 0, 0, 0, "Deletes the active position"); - uiButSetFunc(bt, colorband_del_cb, coba, NULL); - uiDefButS(block, ROW, event, "E", xs+10.0f*unit,butr->ymin+20.0f,unit,20, &coba->ipotype, 5.0, 1.0, 0, 0, "Sets interpolation type 'Ease' (quadratic) "); - uiDefButS(block, ROW, event, "C", xs+11.0f*unit,butr->ymin+20.0f,unit,20, &coba->ipotype, 5.0, 3.0, 0, 0, "Sets interpolation type Cardinal"); - uiDefButS(block, ROW, event, "L", xs+12.0f*unit,butr->ymin+20.0f,unit,20, &coba->ipotype, 5.0, 0.0, 0, 0, "Sets interpolation type Linear"); - uiDefButS(block, ROW, event, "S", xs+13.0f*unit,butr->ymin+20.0f,unit,20, &coba->ipotype, 5.0, 2.0, 0, 0, "Sets interpolation type B-Spline"); - - uiDefBut(block, BUT_COLORBAND, event, "", xs,butr->ymin,butr->xmax-butr->xmin,20.0f, coba, 0, 0, 0, 0, ""); - uiBlockEndAlign(block); - -} - static void texture_panel_colors(Tex *tex) { uiBlock *block; @@ -4833,6 +4885,7 @@ void texture_panels() break; case TEX_POINTDENSITY: texture_panel_pointdensity(tex); + texture_panel_pointdensity_modify(tex); break; } } |