[Bf-blender-cvs] [4067ab3] master: Fix T48991: some particles emitted at a distance from object.

Alexander Gavrilov noreply at git.blender.org
Mon Aug 1 21:15:31 CEST 2016


Commit: 4067ab38ab6035f71b6ce3f2f610000411160d21
Author: Alexander Gavrilov
Date:   Mon Aug 1 21:45:42 2016 +0300
Branches: master
https://developer.blender.org/rB4067ab38ab6035f71b6ce3f2f610000411160d21

Fix T48991: some particles emitted at a distance from object.

The cause seems to be that despite dt_frac being computed as
1/(subframes+1) with integer subframes value, it doesn't always
add up to exactly 1.0 due to precision limitations. If the sum
is similar to 1.00000???, the last subframe is skipped, and all
particles that were supposed to be emitted in that interval are
emitted next frame, with the code working incorrectly due to
skewed time range.

To fix, separate the code from the dynamic timestep feature that
adjusts the last subframe length into a separate function, and
use it even when dynamic timestep is disabled.

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

M	source/blender/blenkernel/intern/particle_system.c

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

diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index e7561ee..8e3e2f5 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -3311,7 +3311,7 @@ static float get_base_time_step(ParticleSettings *part)
 	return 1.0f / (float) (part->subframes + 1);
 }
 /* Update time step size to suit current conditions. */
-static float update_timestep(ParticleSystem *psys, ParticleSimulationData *sim, float t_frac)
+static void update_timestep(ParticleSystem *psys, ParticleSimulationData *sim)
 {
 	float dt_target;
 	if (sim->courant_num == 0.0f)
@@ -3331,7 +3331,10 @@ static float update_timestep(ParticleSystem *psys, ParticleSimulationData *sim,
 		psys->dt_frac = interpf(dt_target, psys->dt_frac, TIMESTEP_EXPANSION_FACTOR);
 	else
 		psys->dt_frac = dt_target;
+}
 
+static float sync_timestep(ParticleSystem *psys, float t_frac)
+{
 	/* Sync with frame end if it's close. */
 	if (t_frac == 1.0f)
 		return psys->dt_frac;
@@ -3991,7 +3994,9 @@ static void system_step(ParticleSimulationData *sim, float cfra, const bool use_
 				printf("%f,%f,%f,%f\n", cfra+dframe+t_frac - 1.f, t_frac, dt_frac, sim->courant_num);
 #endif
 				if (part->time_flag & PART_TIME_AUTOSF)
-					dt_frac = update_timestep(psys, sim, t_frac);
+					update_timestep(psys, sim);
+				/* Even without AUTOSF dt_frac may not add up to 1.0 due to float precision. */
+				dt_frac = sync_timestep(psys, t_frac);
 			}
 		}
 	}




More information about the Bf-blender-cvs mailing list