[Bf-blender-cvs] [49cf27d] gooseberry: Smoke sim option for emitting color based on particle textures.

Lukas Tönne noreply at git.blender.org
Fri Mar 27 10:36:54 CET 2015


Commit: 49cf27d39e0cd22ffef9d09d335f3ee69889ab45
Author: Lukas Tönne
Date:   Fri Mar 27 10:31:31 2015 +0100
Branches: gooseberry
https://developer.blender.org/rB49cf27d39e0cd22ffef9d09d335f3ee69889ab45

Smoke sim option for emitting color based on particle textures.

When using a particle inflow object, there is now an option "Set Color"
which uses particle texture color to override the uniform smoke emission
color.

Particles must have one or more textures with the "Color" influence
enabled (the resulting color can be visualized in the viewport using the
"Texture" display option). The color will then replace the default smoke
flow setting and allows variable color per particle.

Combined with "Strand/Particle" texture mapping this can also be used
to change the particle emission color over the lifetime of particles or
make variable colors for each particle in the system.

Note that this currently does not work with child particles.

===================================================================

M	release/scripts/startup/bl_ui/properties_physics_smoke.py
M	source/blender/blenkernel/intern/smoke.c
M	source/blender/makesdna/DNA_smoke_types.h
M	source/blender/makesrna/intern/rna_smoke.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_physics_smoke.py b/release/scripts/startup/bl_ui/properties_physics_smoke.py
index b2f7962..74d9019 100644
--- a/release/scripts/startup/bl_ui/properties_physics_smoke.py
+++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py
@@ -82,6 +82,8 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel):
             layout.prop(flow, "smoke_flow_type", expand=False)
 
             if flow.smoke_flow_type != "OUTFLOW":
+                use_const_color = False
+
                 split = layout.split()
                 col = split.column()
                 col.label(text="Flow Source:")
@@ -90,6 +92,10 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel):
                     col.label(text="Particle System:")
                     col.prop_search(flow, "particle_system", ob, "particle_systems", text="")
                     col.prop(flow, "use_particle_size", text="Set Size")
+                    col.prop(flow, "use_particle_texture_color", text="Set Color")
+                    # disable const color button when using particle color
+                    use_const_color = not flow.use_particle_texture_color
+
                     sub = col.column()
                     sub.active = flow.use_particle_size
                     sub.prop(flow, "particle_size")
@@ -113,7 +119,9 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel):
                 if flow.smoke_flow_type in {'SMOKE', 'BOTH'}:
                     sub.prop(flow, "density")
                     sub.prop(flow, "temperature")
-                    sub.prop(flow, "smoke_color")
+                    subsub = sub.column()
+                    subsub.active = use_const_color
+                    subsub.prop(flow, "smoke_color")
                 if flow.smoke_flow_type in {'FIRE', 'BOTH'}:
                     sub.prop(flow, "fuel_amount")
                 sub.label(text="Sampling:")
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 54e9b8c..f61cf16 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -1027,6 +1027,7 @@ typedef struct EmissionMap {
 	float *velocity;
 	int min[3], max[3], res[3];
 	int hmin[3], hmax[3], hres[3];
+	float *color;
 	int total_cells, valid;
 } EmissionMap;
 
@@ -1071,7 +1072,7 @@ static void clampBoundsInDomain(SmokeDomainSettings *sds, int min[3], int max[3]
 	}
 }
 
-static void em_allocateData(EmissionMap *em, bool use_velocity, int hires_mul)
+static void em_allocateData(EmissionMap *em, bool use_velocity, bool use_color, int hires_mul)
 {
 	int i, res[3];
 
@@ -1087,6 +1088,8 @@ static void em_allocateData(EmissionMap *em, bool use_velocity, int hires_mul)
 	em->influence = MEM_callocN(sizeof(float) * em->total_cells, "smoke_flow_influence");
 	if (use_velocity)
 		em->velocity = MEM_callocN(sizeof(float) * em->total_cells * 3, "smoke_flow_velocity");
+	if (use_color)
+		em->color = MEM_callocN(sizeof(float) * em->total_cells * 3, "smoke_flow_color");
 
 	/* allocate high resolution map if required */
 	if (hires_mul > 1) {
@@ -1111,6 +1114,8 @@ static void em_freeData(EmissionMap *em)
 		MEM_freeN(em->influence_high);
 	if (em->velocity)
 		MEM_freeN(em->velocity);
+	if (em->color)
+		MEM_freeN(em->color);
 }
 
 static void em_combineMaps(EmissionMap *output, EmissionMap *em2, int hires_multiplier, int additive, float sample_size)
@@ -1133,7 +1138,7 @@ static void em_combineMaps(EmissionMap *output, EmissionMap *em2, int hires_mult
 		}
 	}
 	/* allocate output map */
-	em_allocateData(output, (em1.velocity || em2->velocity), hires_multiplier);
+	em_allocateData(output, (em1.velocity || em2->velocity), (em1.color || em2->color), hires_multiplier);
 
 	/* base resolution inputs */
 	for (x = output->min[0]; x < output->max[0]; x++)
@@ -1152,6 +1157,9 @@ static void em_combineMaps(EmissionMap *output, EmissionMap *em2, int hires_mult
 					if (output->velocity && em1.velocity) {
 						copy_v3_v3(&output->velocity[index_out * 3], &em1.velocity[index_in * 3]);
 					}
+					if (output->color && em1.color) {
+						copy_v3_v3(&output->color[index_out * 3], &em1.color[index_in * 3]);
+					}
 				}
 
 				/* apply second input if in range */
@@ -1173,6 +1181,13 @@ static void em_combineMaps(EmissionMap *output, EmissionMap *em2, int hires_mult
 						output->velocity[index_out * 3 + 1] = ADD_IF_LOWER(output->velocity[index_out * 3 + 1], em2->velocity[index_in * 3 + 1]);
 						output->velocity[index_out * 3 + 2] = ADD_IF_LOWER(output->velocity[index_out * 3 + 2], em2->velocity[index_in * 3 + 2]);
 					}
+					if (output->color && em2->color) {
+						/* mix by influence */
+						float f1 = output->influence[index_out];
+						float f2 = em2->influence[index_in];
+						float f = f1 + f2 > 0.0f ? f1 / (f1 + f2) : 0.5f;
+						interp_v3_v3v3(&output->color[index_out * 3], &output->color[index_out * 3], &em2->color[index_in * 3], f);
+					}
 				}
 	} // low res loop
 
@@ -1224,6 +1239,7 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke
 		ParticleSystem *psys = sfs->psys;
 		float *particle_pos;
 		float *particle_vel;
+		float *particle_texcol;
 		int totpart = psys->totpart, totchild;
 		int p = 0;
 		int valid_particles = 0;
@@ -1270,6 +1286,11 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke
 			bounds_margin = (int)ceil(solid + smooth);
 		}
 
+		if (sfs->flags & MOD_SMOKE_FLOW_USE_PART_TEXCOLOR)
+			particle_texcol = MEM_callocN(sizeof(float) * (totpart + totchild) * 3, "smoke_flow_particles");
+		else
+			particle_texcol = NULL;
+
 		/* calculate local position for each particle */
 		for (p = 0; p < totpart + totchild; p++)
 		{
@@ -1303,6 +1324,16 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke
 				BLI_kdtree_insert(tree, valid_particles, pos);
 			}
 
+			if (particle_texcol) {
+				if (p < totpart) {
+					ParticleTexture ptex;
+					psys_get_texture(&sim, &psys->particles[p], &ptex, PAMAP_COLOR, state.time);
+					copy_v3_v3(&particle_texcol[valid_particles * 3], ptex.color);
+				}
+				else
+					zero_v3(&particle_texcol[valid_particles * 3]);
+			}
+
 			/* calculate emission map bounds */
 			em_boundInsert(em, pos);
 			valid_particles++;
@@ -1310,7 +1341,7 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke
 
 		/* set emission map */
 		clampBoundsInDomain(sds, em->min, em->max, NULL, NULL, bounds_margin, dt);
-		em_allocateData(em, sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY, hires_multiplier);
+		em_allocateData(em, sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY, sfs->flags & MOD_SMOKE_FLOW_USE_PART_TEXCOLOR, hires_multiplier);
 
 		if (!(sfs->flags & MOD_SMOKE_FLOW_USE_PART_SIZE)) {
 			for (p = 0; p < valid_particles; p++)
@@ -1342,6 +1373,9 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke
 				{
 					VECADDFAC(&em->velocity[index * 3], &em->velocity[index * 3], &particle_vel[p * 3], sfs->vel_multi);
 				}
+				if (particle_texcol && em->color) {
+					copy_v3_v3(&em->color[index * 3], &particle_texcol[p * 3]);
+				}
 			}   // particles loop
 		}
 		else if (valid_particles > 0) { // MOD_SMOKE_FLOW_USE_PART_SIZE
@@ -1391,6 +1425,9 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke
 								{
 									VECADDFAC(&em->velocity[index * 3], &em->velocity[index * 3], &particle_vel[nearest.index * 3], sfs->vel_multi);
 								}
+								if (particle_texcol && em->color) {
+									copy_v3_v3(&em->color[index * 3], &particle_texcol[nearest.index * 3]);
+								}
 							}
 						}
 
@@ -1428,6 +1465,8 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke
 			MEM_freeN(particle_pos);
 		if (particle_vel)
 			MEM_freeN(particle_vel);
+		if (particle_texcol)
+			MEM_freeN(particle_texcol);
 	}
 }
 
@@ -1641,7 +1680,7 @@ static void emit_from_derivedmesh(Object *flow_ob, SmokeDomainSettings *sds, Smo
 
 		/* set emission map */
 		clampBoundsInDomain(sds, em->min, em->max, NULL, NULL, (int)ceil(sfs->surface_distance), dt);
-		em_allocateData(em, sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY, hires_multiplier);
+		em_allocateData(em, sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY, false, hires_multiplier);
 
 		/* setup loop bounds */
 		for (i = 0; i < 3; i++) {
@@ -1983,7 +2022,7 @@ BLI_INLINE void apply_outflow_fields(int index, float *density, float *heat, flo
 	}
 }
 
-BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value, int index, float *density, float *heat, float *fuel, float *react, float *color_r, float *color_g, float *color_b)
+BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value, const float *color_value, int index, float *density, float *heat, float *fuel, float *react, float *color_r, float *color_g, float *color_b)
 {
 	int absolute_flow = (sfs->flags & MOD_SMOKE_FLOW_ABSOLUTE);
 	float dens_old = density[index];
@@ -2020,9 +2059,10 @@ BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value
 	/* set color */
 	if (color_r && dens_flow) {
 		float total_dens = density[index] / (dens_old + dens_flow);
-		color_r[index] = (color_r[index] + sfs->color[0] * dens_flow) * total_dens;
-		color_g[index] = (color_g[index] + sfs->color[1] * dens_flow) * total_dens;
-		color_b[index] = (color_b[index] + sfs->color[2] * dens_flow) * total_dens;
+		const float *color = (color_value ? color_value : sfs->color);
+		color_r[index] = (color_r[index] + color[0] * dens_flow) * total_dens;
+		color_g[index] = (color_g[index] + color[1] * dens_flow) * total_dens;
+		color_b[index] = (color_b[index] + color[2] * dens_flow) * total_dens;
 	}
 
 	/* set fire reaction coordinate */
@@ -2169,7 +2209,10 @@ static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sd
 				}
 				/* activate color field if flows add smoke with varying colors */
 				if (sfs->type != MOD_SMOKE_FLOW_TYPE_FIRE && sfs->density) {
-					if (!(active_fields & SM_ACTIVE_COLOR_SET)) {
+					if (sfs->flags & MOD_SMOKE_FLOW_USE_PART_TEXCOLOR) {
+						active_fields |= SM_ACTIVE_COLORS;
+					}
+					else if (!(active_fiel

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list