[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [33692] trunk/blender/source/blender: Fix for [#25218] No smoke is emitted when particle system starts and ends on same frame

Janne Karhu jhkarh at gmail.com
Wed Dec 15 18:05:34 CET 2010


Revision: 33692
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=33692
Author:   jhk
Date:     2010-12-15 18:05:34 +0100 (Wed, 15 Dec 2010)

Log Message:
-----------
Fix for [#25218] No smoke is emitted when particle system starts and ends on same frame
* Depsgraph wasn't updated properly for smoke flow collision object dependencies.
* Smoke also wasn't properly using the actual emission frame of the flow particles.
* There was a lot of bloated logic in some parts of particle code so this fix turned into a small scale cleanup operation.
** As a result particle updating and cache usage should be a bit more stable too.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/particle.c
    trunk/blender/source/blender/blenkernel/intern/particle_system.c
    trunk/blender/source/blender/blenkernel/intern/pointcache.c
    trunk/blender/source/blender/blenkernel/intern/smoke.c
    trunk/blender/source/blender/modifiers/intern/MOD_smoke.c

Modified: trunk/blender/source/blender/blenkernel/intern/particle.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle.c	2010-12-15 16:57:56 UTC (rev 33691)
+++ trunk/blender/source/blender/blenkernel/intern/particle.c	2010-12-15 17:05:34 UTC (rev 33692)
@@ -4193,11 +4193,11 @@
 
 	if(pa) {
 		if(!always)
-			if((pa->alive==PARS_UNBORN && (part->flag & PART_UNBORN)==0)
-				|| (pa->alive==PARS_DEAD && (part->flag & PART_DIED)==0))
+			if((cfra < pa->time && (part->flag & PART_UNBORN)==0)
+				|| (cfra > pa->dietime && (part->flag & PART_DIED)==0))
 				return 0;
 
-		state->time = MIN2(state->time, pa->dietime);
+		cfra = MIN2(cfra, pa->dietime);
 	}
 
 	if(sim->psys->flag & PSYS_KEYED){
@@ -4223,16 +4223,15 @@
 				calc_latt_deform(sim->psys->lattice, state->co,1.0f);
 		}
 		else{
-			if(pa->state.time==state->time || ELEM(part->phystype,PART_PHYS_NO,PART_PHYS_KEYED)
-				|| pa->prev_state.time <= 0.0f)
+			if(pa->state.time==cfra || ELEM(part->phystype,PART_PHYS_NO,PART_PHYS_KEYED))
 				copy_particle_key(state, &pa->state, 1);
-			else if(pa->prev_state.time==state->time)
+			else if(pa->prev_state.time==cfra)
 				copy_particle_key(state, &pa->prev_state, 1);
 			else {
 				float dfra, frs_sec = sim->scene->r.frs_sec;
 				/* let's interpolate to try to be as accurate as possible */
-				if(pa->state.time + 2.0f >= state->time && pa->prev_state.time - 2.0f <= state->time) {
-					if(pa->prev_state.time >= pa->state.time) {
+				if(pa->state.time + 2.f >= state->time && pa->prev_state.time - 2.f <= state->time) {
+					if(pa->prev_state.time >= pa->state.time || pa->prev_state.time < 0.f) {
 						/* prev_state is wrong so let's not use it, this can happen at frames 1, 0 or particle birth */
 						dfra = state->time - pa->state.time;
 
@@ -4258,7 +4257,7 @@
 						psys_interpolate_particle(-1, keys, keytime, state, 1);
 						
 						/* convert back to real velocity */
-						mul_v3_fl(state->vel, 1.0f / (dfra * timestep));
+						mul_v3_fl(state->vel, 1.f / (dfra * timestep));
 
 						interp_v3_v3v3(state->ave, keys[1].ave, keys[2].ave, keytime);
 						interp_qt_qtqt(state->rot, keys[1].rot, keys[2].rot, keytime);

Modified: trunk/blender/source/blender/blenkernel/intern/particle_system.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle_system.c	2010-12-15 16:57:56 UTC (rev 33691)
+++ trunk/blender/source/blender/blenkernel/intern/particle_system.c	2010-12-15 17:05:34 UTC (rev 33692)
@@ -3749,80 +3749,59 @@
 	ParticleSystem *psys = sim->psys;
 	ParticleSettings *part = psys->part;
 	PointCache *cache = psys->pointcache;
-	PTCacheID pid, *use_cache = NULL;
+	PTCacheID ptcacheid, *pid = NULL;
 	PARTICLE_P;
-	int oldtotpart;
-	float disp; /*, *vg_vel= 0, *vg_tan= 0, *vg_rot= 0, *vg_size= 0; */
-	int init= 0, emit= 0; //, only_children_changed= 0;
-	int framenr, framedelta, startframe = 0, endframe = 100;
+	float disp, cache_cfra = cfra; /*, *vg_vel= 0, *vg_tan= 0, *vg_rot= 0, *vg_size= 0; */
+	int startframe = 0, endframe = 100;
 
-	framenr= (int)sim->scene->r.cfra;
-	framedelta= framenr - cache->simframe;
-
 	/* cache shouldn't be used for hair or "continue physics" */
 	if(part->type != PART_HAIR && BKE_ptcache_get_continue_physics() == 0) {
-		BKE_ptcache_id_from_particles(&pid, sim->ob, psys);
-		use_cache = &pid;
-	}
+		psys_clear_temp_pointcache(psys);
 
-	if(use_cache) {
-		psys_clear_temp_pointcache(sim->psys);
-
 		/* set suitable cache range automatically */
 		if((cache->flag & (PTCACHE_BAKING|PTCACHE_BAKED))==0)
-			psys_get_pointcache_start_end(sim->scene, sim->psys, &cache->startframe, &cache->endframe);
+			psys_get_pointcache_start_end(sim->scene, psys, &cache->startframe, &cache->endframe);
+
+		pid = &ptcacheid;
+		BKE_ptcache_id_from_particles(pid, sim->ob, psys);
 		
-		BKE_ptcache_id_time(&pid, sim->scene, 0.0f, &startframe, &endframe, NULL);
+		BKE_ptcache_id_time(pid, sim->scene, 0.0f, &startframe, &endframe, NULL);
 
-		/* simulation is only active during a specific period */
-		if(framenr < startframe) {
-			BKE_ptcache_read_cache(use_cache, startframe, sim->scene->r.frs_sec);
-			/* set correct particle state and reset particles */
-			cached_step(sim, cfra);
-			return;
-		}
-		else if(framenr > endframe) {
-			framenr= endframe;
-		}
-		else if(framenr == startframe) {
-			BKE_ptcache_id_reset(sim->scene, use_cache, PTCACHE_RESET_OUTDATED);
-			BKE_ptcache_validate(cache, framenr);
+		/* clear everythin on start frame */
+		if((int)cfra == startframe) {
+			BKE_ptcache_id_reset(sim->scene, pid, PTCACHE_RESET_OUTDATED);
+			BKE_ptcache_validate(cache, startframe);
 			cache->flag &= ~PTCACHE_REDO_NEEDED;
 		}
+		
+		CLAMP(cache_cfra, startframe, endframe);
 	}
 
-/* 1. emit particles */
-
-	/* verify if we need to reallocate */
-	oldtotpart = psys->totpart;
-
-	emit = emit_particles(sim, use_cache, cfra);
-	if(use_cache && emit > 0)
-		BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, cfra);
-	init = emit*emit + (psys->recalc & PSYS_RECALC_RESET);
-
-	if(init) {
+/* 1. emit particles and redo particles if needed */
+	if(emit_particles(sim, pid, cfra) || psys->recalc & PSYS_RECALC_RESET) {
 		distribute_particles(sim, part->from);
 		initialize_all_particles(sim);
-		reset_all_particles(sim, 0.0, cfra, oldtotpart);
+		reset_all_particles(sim, 0.0, cfra, 0);
 
 		/* flag for possible explode modifiers after this system */
 		sim->psmd->flag |= eParticleSystemFlag_Pars;
+
+		BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, cfra);
 	}
 
 /* 2. try to read from the cache */
-	if(use_cache) {
-		int cache_result = BKE_ptcache_read_cache(use_cache, cfra, sim->scene->r.frs_sec);
+	if(pid) {
+		int cache_result = BKE_ptcache_read_cache(pid, cache_cfra, sim->scene->r.frs_sec);
 
 		if(ELEM(cache_result, PTCACHE_READ_EXACT, PTCACHE_READ_INTERPOLATED)) {
 			cached_step(sim, cfra);
 			update_children(sim);
 			psys_update_path_cache(sim, cfra);
 
-			BKE_ptcache_validate(cache, framenr);
+			BKE_ptcache_validate(cache, (int)cache_cfra);
 
 			if(cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED)
-				BKE_ptcache_write_cache(use_cache, framenr);
+				BKE_ptcache_write_cache(pid, (int)cache_cfra);
 
 			return;
 		}
@@ -3837,7 +3816,7 @@
 
 		/* if on second frame, write cache for first frame */
 		if(psys->cfra == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
-			BKE_ptcache_write_cache(use_cache, startframe);
+			BKE_ptcache_write_cache(pid, startframe);
 	}
 	else
 		BKE_ptcache_invalidate(cache);
@@ -3860,7 +3839,7 @@
 		
 		/* handle negative frame start at the first frame by doing
 		 * all the steps before the first frame */
-		if(framenr == startframe && part->sta < startframe)
+		if((int)cfra == startframe && part->sta < startframe)
 			totframesback = (startframe - (int)part->sta);
 		
 		for(dframe=-totframesback; dframe<=0; dframe++) {
@@ -3875,10 +3854,10 @@
 	}
 	
 /* 4. only write cache starting from second frame */
-	if(use_cache) {
-		BKE_ptcache_validate(cache, framenr);
-		if(framenr != startframe)
-			BKE_ptcache_write_cache(use_cache, framenr);
+	if(pid) {
+		BKE_ptcache_validate(cache, (int)cache_cfra);
+		if((int)cache_cfra != startframe)
+			BKE_ptcache_write_cache(pid, (int)cache_cfra);
 	}
 
 	update_children(sim);

Modified: trunk/blender/source/blender/blenkernel/intern/pointcache.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/pointcache.c	2010-12-15 16:57:56 UTC (rev 33691)
+++ trunk/blender/source/blender/blenkernel/intern/pointcache.c	2010-12-15 17:05:34 UTC (rev 33692)
@@ -1883,8 +1883,7 @@
 {
 	int len; /* store the length of the string */
 	int i;
-	int sta = pid->cache->startframe;
-	int end = pid->cache->endframe;
+	int sta, end;
 
 	/* mode is same as fopen's modes */
 	DIR *dir; 
@@ -1894,9 +1893,12 @@
 	char path_full[MAX_PTCACHE_FILE];
 	char ext[MAX_PTCACHE_PATH];
 
-	if(!pid->cache || pid->cache->flag & PTCACHE_BAKED)
+	if(!pid || !pid->cache || pid->cache->flag & PTCACHE_BAKED)
 		return;
 
+	sta = pid->cache->startframe;
+	end = pid->cache->endframe;
+
 #ifndef DURIAN_POINTCACHE_LIB_OK
 	/* don't allow clearing for linked objects */
 	if(pid->ob->id.lib)

Modified: trunk/blender/source/blender/blenkernel/intern/smoke.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/smoke.c	2010-12-15 16:57:56 UTC (rev 33691)
+++ trunk/blender/source/blender/blenkernel/intern/smoke.c	2010-12-15 17:05:34 UTC (rev 33692)
@@ -973,9 +973,9 @@
 					
 					if(sfs && sfs->psys && sfs->psys->part && sfs->psys->part->type==PART_EMITTER) // is particle system selected
 					{
+						ParticleSimulationData sim;
 						ParticleSystem *psys = sfs->psys;
 						ParticleSettings *part=psys->part;
-						ParticleData *pa = NULL;							
 						int p = 0;								
 						float *density = smoke_get_density(sds->fluid);								
 						float *bigdensity = smoke_turbulence_get_density(sds->wt);								
@@ -995,6 +995,10 @@
 						*/
 						float *temp_emission_map = NULL;
 
+						sim.scene = scene;
+						sim.ob = otherobj;
+						sim.psys = psys;
+
 						// initialize temp emission map
 						if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW))
 						{
@@ -1007,19 +1011,26 @@
 						}
 														
 						// mostly copied from particle code								
-						for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++)								
-						{									
-							int cell[3];									
-							size_t i = 0;									
-							size_t index = 0;									
-							int badcell = 0;																		
-							if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue;									
-							else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue;									
-							else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;																		
+						for(p=0; p<psys->totpart; p++)								
+						{
+							int cell[3];
+							size_t i = 0;
+							size_t index = 0;
+							int badcell = 0;
+							ParticleKey state;
+
+							if(psys->particles[p].flag & (PARS_NO_DISP|PARS_UNEXIST))
+								continue;
+
+							state.time = smd->time;
+
+							if(psys_get_particle_state(&sim, p, &state, 0) == 0)
+								continue;
+							
 							// VECCOPY(pos, pa->state.co);									
 							// mul_m4_v3(ob->imat, pos);																		
 							// 1. get corresponding cell	

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list