[Bf-blender-cvs] [01f6b87] hair_system: Make Bullet world stepping and rebuild less dependent on point cache.

Lukas Tönne noreply at git.blender.org
Tue Aug 5 15:21:28 CEST 2014


Commit: 01f6b871233c22e232a16726feb4afe195589da2
Author: Lukas Tönne
Date:   Mon Aug 4 18:13:07 2014 +0200
Branches: hair_system
https://developer.blender.org/rB01f6b871233c22e232a16726feb4afe195589da2

Make Bullet world stepping and rebuild less dependent on point cache.

This means the Bullet rigid body world will be created even when a baked
rigid body cache exists and stepping will also happen regardless of
baked or cached results being available.

The rationale is that the Bullet DynamicsWorld stepping may be used for
other systems as well (hair, later particles) which do not necessarily
use the same cache system. Rather than disabling stepping and collision
detection altogether the cached RigidBodies should rather be set to
kinematic, so that other un-cached participants can still use them for
collisions. This will also be an important prerequisite for later
layering of simulations with pre-cached or animated elements.

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

M	source/blender/blenkernel/BKE_rigidbody.h
M	source/blender/blenkernel/intern/rigidbody.c
M	source/blender/blenkernel/intern/scene.c

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

diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h
index bcffedf..8e4bd81 100644
--- a/source/blender/blenkernel/BKE_rigidbody.h
+++ b/source/blender/blenkernel/BKE_rigidbody.h
@@ -79,7 +79,7 @@ struct RigidBodyWorld *BKE_rigidbody_get_world(struct Scene *scene);
 bool BKE_rigidbody_check_sim_running(struct RigidBodyWorld *rbw, float ctime);
 void BKE_rigidbody_cache_reset(struct RigidBodyWorld *rbw);
 void BKE_rigidbody_rebuild_world(struct Scene *scene, float ctime);
-bool BKE_rigidbody_do_simulation(struct Scene *scene, float ctime, void (*tickcb)(void *tickdata, float timestep), void *tickdata);
+void BKE_rigidbody_do_simulation(struct Scene *scene, float ctime, void (*tickcb)(void *tickdata, float timestep), void *tickdata);
 
 
 /* -------------- */
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index fbaf099..a373600 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -833,33 +833,36 @@ void BKE_rigidbody_rebuild_world(Scene *scene, float ctime)
 		cache->flag |= PTCACHE_OUTDATED;
 	}
 
-	if (ctime == startframe + 1 && rbw->ltime == startframe) {
-		if (cache->flag & PTCACHE_OUTDATED) {
-			BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
-			rigidbody_world_build(scene, rbw, true);
-			BKE_ptcache_validate(cache, (int)ctime);
-			cache->last_exact = 0;
-			cache->flag &= ~PTCACHE_REDO_NEEDED;
-		}
+	bool rebuild = (cache->flag & PTCACHE_OUTDATED);
+	rigidbody_world_build(scene, rbw, rebuild);
+	
+	bool is_startframe = (ctime == startframe + 1 && rbw->ltime == startframe);
+	if (is_startframe) {
+		BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
+		BKE_ptcache_validate(cache, (int)ctime);
+		cache->last_exact = 0;
+		cache->flag &= ~PTCACHE_REDO_NEEDED;
 	}
 }
 
 /* Run RigidBody simulation for the specified physics world */
-bool BKE_rigidbody_do_simulation(Scene *scene, float ctime, void (*tickcb)(void *tickdata, float timestep), void *tickdata)
+void BKE_rigidbody_do_simulation(Scene *scene, float ctime, void (*tickcb)(void *tickdata, float timestep), void *tickdata)
 {
-	float timestep;
 	RigidBodyWorld *rbw = scene->rigidbody_world;
 	PointCache *cache;
 	PTCacheID pid;
 	int startframe, endframe;
+	bool cache_read, cache_baked;
+	float timestep;
 
 	BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw);
 	BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL);
 	cache = rbw->pointcache;
+	cache_baked = cache->flag & PTCACHE_BAKED;
 
 	if (ctime <= startframe) {
 		rbw->ltime = startframe;
-		return true; /* is ok, just nothing to simulate before the start frame */
+		return;
 	}
 	/* make sure we don't go out of cache frame range */
 	else if (ctime > endframe) {
@@ -867,49 +870,53 @@ bool BKE_rigidbody_do_simulation(Scene *scene, float ctime, void (*tickcb)(void
 	}
 
 	/* don't try to run the simulation if we don't have a world yet but allow reading baked cache */
-	if (rbw->physics_world == NULL && !(cache->flag & PTCACHE_BAKED))
-		return false;
+	if (rbw->physics_world == NULL && !cache_baked)
+		return;
 	else if (rbw->objects == NULL)
 		rigidbody_update_ob_array(rbw);
 
 	/* try to read from cache */
+	cache_read = BKE_ptcache_read(&pid, ctime);
 	// RB_TODO deal with interpolated, old and baked results
-	if (BKE_ptcache_read(&pid, ctime)) {
+	if (cache_read) {
 		BKE_ptcache_validate(cache, (int)ctime);
 		rbw->ltime = ctime;
 		/* XXX TODO run the stepping loop anyway, but then set all rigid bodies
 		 * to animated and interpolate cached data!
 		 * The collision info may still be needed for other solvers
 		 */
-		return true;
+		return;
 	}
 
 	/* advance simulation, we can only step one frame forward */
-	if (ctime == rbw->ltime + 1 && !(cache->flag & PTCACHE_BAKED)) {
-		/* write cache for first frame when on second frame */
-		if (rbw->ltime == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact == 0)) {
-			BKE_ptcache_write(&pid, startframe);
-		}
-
+	if (ctime == rbw->ltime + 1) {
+		
 		/* update and validate simulation */
 		rigidbody_world_build(scene, rbw, false);
-
+		
+		if (!cache_baked) {
+			/* write cache for first frame when on second frame */
+			if (rbw->ltime == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact == 0)) {
+				BKE_ptcache_write(&pid, startframe);
+			}
+		}
+		
 		/* calculate how much time elapsed since last step in seconds */
 		timestep = 1.0f / (float)FPS * (ctime - rbw->ltime) * rbw->time_scale;
 		/* step simulation by the requested timestep, steps per second are adjusted to take time scale into account */
 		RB_dworld_step_simulation(rbw->physics_world, timestep, INT_MAX, 1.0f / (float)rbw->steps_per_second * min_ff(rbw->time_scale, 1.0f),
 		                          tickcb, tickdata, false);
-
+		
 		rigidbody_world_apply(scene, rbw);
-
-		/* write cache for current frame */
-		BKE_ptcache_validate(cache, (int)ctime);
-		BKE_ptcache_write(&pid, (unsigned int)ctime);
-
+		
+		if (!cache_baked) {
+			/* write cache for current frame */
+			BKE_ptcache_validate(cache, (int)ctime);
+			BKE_ptcache_write(&pid, (unsigned int)ctime);
+		}
+		
 		rbw->ltime = ctime;
 	}
-	
-	return true;
 }
 /* ************************************** */
 
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 8df9137..ebedcb7 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1295,46 +1295,12 @@ static void scene_simulation_tick(void *vdata, float timestep)
 	data->t += timestep;
 }
 
-/* fallback implementation for global simulation solvers,
- * in case Bullet time stepping is not available.
- */
-static void scene_do_simulation_step(Scene *scene, float ctime)
-{
-#if 0
-	const int maxSubSteps = INT_MAX;
-	const float fixedTimeStep = 1.0f / (float)rbw->steps_per_second * min_ff(rbw->time_scale, 1.0f);
-	int numSimulationSubSteps = 0;
-	float local_time;
-	
-	//fixed timestep with interpolation
-	local_time += timeStep;
-	if (local_time >= fixedTimeStep)
-	{
-		numSimulationSubSteps = int( local_time / fixedTimeStep);
-		local_time -= numSimulationSubSteps * fixedTimeStep;
-	}
-	
-	if (numSimulationSubSteps) {
-		//clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
-		int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps) ? maxSubSteps : numSimulationSubSteps;
-		
-		for (int i=0;i<clampedSimulationSteps;i++)
-		{
-			scene_tick(scene, fixedTimeStep);
-		}
-	}
-	
-	return numSimulationSubSteps;
-#endif
-}
-
 static void scene_do_rb_simulation_recursive(Scene *scene, float cfra)
 {
 	if (scene->set)
 		scene_do_rb_simulation_recursive(scene->set, cfra);
 
 	{
-		bool stepped = false;
 		SceneSimStepData data;
 		float frametime = FRA2TIME(1);
 		
@@ -1344,15 +1310,13 @@ static void scene_do_rb_simulation_recursive(Scene *scene, float cfra)
 		data.t1 = data.t0 + frametime;
 		data.t = data.t0;
 		
-		scene_simulation_objects_pre_step(scene, data.t0);
-		
-		if (BKE_scene_check_rigidbody_active(scene))
-			stepped |= BKE_rigidbody_do_simulation(scene, cfra, scene_simulation_tick, &data);
-	
-		if (!stepped)
-			scene_do_simulation_step(scene, cfra);
-		
-		scene_simulation_objects_post_step(scene, data.t1);
+		if (BKE_scene_check_rigidbody_active(scene)) {
+			scene_simulation_objects_pre_step(scene, data.t0);
+			
+			BKE_rigidbody_do_simulation(scene, cfra, scene_simulation_tick, &data);
+			
+			scene_simulation_objects_post_step(scene, data.t1);
+		}
 	}
 }
 
@@ -2038,7 +2002,7 @@ bool BKE_scene_check_color_management_enabled(const Scene *scene)
 
 bool BKE_scene_check_rigidbody_active(const Scene *scene)
 {
-	return scene && scene->rigidbody_world && scene->rigidbody_world->group && !(scene->rigidbody_world->flag & RBW_FLAG_MUTED);
+	return scene && scene->rigidbody_world && !(scene->rigidbody_world->flag & RBW_FLAG_MUTED);
 }
 
 int BKE_render_num_threads(const RenderData *rd)




More information about the Bf-blender-cvs mailing list