[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17370] branches/sim_physics/source/ blender: Point Density texture: colouring

Matt Ebb matt at mke3.net
Sun Nov 9 02:16:12 CET 2008


Revision: 17370
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17370
Author:   broken
Date:     2008-11-09 02:16:12 +0100 (Sun, 09 Nov 2008)

Log Message:
-----------
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

Modified Paths:
--------------
    branches/sim_physics/source/blender/blenkernel/intern/texture.c
    branches/sim_physics/source/blender/blenloader/intern/readfile.c
    branches/sim_physics/source/blender/blenloader/intern/writefile.c
    branches/sim_physics/source/blender/makesdna/DNA_texture_types.h
    branches/sim_physics/source/blender/render/intern/source/pointdensity.c
    branches/sim_physics/source/blender/src/buttons_shading.c

Modified: branches/sim_physics/source/blender/blenkernel/intern/texture.c
===================================================================
--- branches/sim_physics/source/blender/blenkernel/intern/texture.c	2008-11-08 23:56:16 UTC (rev 17369)
+++ branches/sim_physics/source/blender/blenkernel/intern/texture.c	2008-11-09 01:16:12 UTC (rev 17370)
@@ -883,7 +883,9 @@
 	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 @@
 	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 @@
 		MEM_freeN(pd->point_data);
 		pd->point_data = NULL;
 	}
+	if(pd->coba) MEM_freeN(pd->coba);
 }
 
 void BKE_free_pointdensity(PointDensity *pd)

Modified: branches/sim_physics/source/blender/blenloader/intern/readfile.c
===================================================================
--- branches/sim_physics/source/blender/blenloader/intern/readfile.c	2008-11-08 23:56:16 UTC (rev 17369)
+++ branches/sim_physics/source/blender/blenloader/intern/readfile.c	2008-11-09 01:16:12 UTC (rev 17370)
@@ -2506,6 +2506,7 @@
 	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 @@
 			}
 			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;
+			}
 		}
 		
 	}

Modified: branches/sim_physics/source/blender/blenloader/intern/writefile.c
===================================================================
--- branches/sim_physics/source/blender/blenloader/intern/writefile.c	2008-11-08 23:56:16 UTC (rev 17369)
+++ branches/sim_physics/source/blender/blenloader/intern/writefile.c	2008-11-09 01:16:12 UTC (rev 17370)
@@ -1335,7 +1335,10 @@
 			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);
 		}

Modified: branches/sim_physics/source/blender/makesdna/DNA_texture_types.h
===================================================================
--- branches/sim_physics/source/blender/makesdna/DNA_texture_types.h	2008-11-08 23:56:16 UTC (rev 17369)
+++ branches/sim_physics/source/blender/makesdna/DNA_texture_types.h	2008-11-09 01:16:12 UTC (rev 17370)
@@ -134,7 +134,10 @@
 	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,8 +154,10 @@
 	short noise_depth;
 	short noise_influence;
 	float noise_fac;
-	float pdpad4;
 	
+	float speed_scale;
+	struct ColorBand *coba;	/* for time -> color */
+	
 } PointDensity;
 
 typedef struct Tex {
@@ -442,7 +447,17 @@
 /* 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
 

Modified: branches/sim_physics/source/blender/render/intern/source/pointdensity.c
===================================================================
--- branches/sim_physics/source/blender/render/intern/source/pointdensity.c	2008-11-08 23:56:16 UTC (rev 17369)
+++ branches/sim_physics/source/blender/render/intern/source/pointdensity.c	2008-11-09 01:16:12 UTC (rev 17370)
@@ -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 @@
 	psys->lattice=psys_get_lattice(ob,psys);
 	
 	pd->point_tree = BLI_bvhtree_new(total_particles, 0.0, 4, 6);
+	make_point_data(pd, total_particles, data_used);
+	pd->totpoints = total_particles;
+	if (data_used & POINT_DATA_VEL) offset = pd->totpoints*3;
 	
-	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");
-	
 	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 @@
 			
 			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 @@
 	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 @@
 		MEM_freeN(pd->point_data);
 		pd->point_data = NULL;
 	}
+	pd->totpoints = 0;
 }
 
 
@@ -263,7 +309,9 @@
 	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 @@
 	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);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list