[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [54577] trunk/blender/source/blender/ blenkernel/intern: Bugfix [#33970] Background Scene does not show animation of rigid body objects

Joshua Leung aligorith at gmail.com
Fri Feb 15 12:49:23 CET 2013


Revision: 54577
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=54577
Author:   aligorith
Date:     2013-02-15 11:49:22 +0000 (Fri, 15 Feb 2013)
Log Message:
-----------
Bugfix [#33970] Background Scene does not show animation of rigid body objects

This was caused by multiple instantiations of the same basic problem. The
rigidbody handling code often assumed that "scene" pointers referred to the
scene where an object participating in the sim resided (and where the rigidbody
world for that sim lived). However, when dealing with background sets, "scene"
often only refers to the active scene, and not the set that the object actually
came from. Hence, the rigidbody code would often (wrongly) conclude that there
was nothing to do.

For example, we may have the following backgound set/scene chaining scenario:
"active"  <-- ... <-- set i (rigidbody objects live here) <-- ... <-- set n

The fix here is a multi-part fix:
1) Moved sim-world calculation from BKE_scene_update_newframe() to
scene_update_tagged_recursive()
    + This is currently the only way that rigidbody sims in background sets will
get calculated, as part of the recursion
     - These checks will get run on each update. <--- FIXME!!!

2) Tweaked depsgraph code so that when checking if there are any time-dependent
features on objects to tag for updating, the checking is done relative to the
scene that the object actually resides in (and not the active scene). Otherwise,
even if we recalculate the sim, the affected objects won't get tagged for
updating. This tagging is needed to actually flush the transforms out of the
RigidBodyObject structs (written by the sim/cache) and into the Object
transforms (obmat's)

3) Removed the requirement for rigidbody world to actually exist before we can
flush rigidbody transforms. In many cases, it should be sufficient to assume
that because the object with rigidbody data attached has been tagged for
updates, it should have updates to perform. Of course, we still check on this
data if we've got it, but that's only if the sim is in the active scene.
   - TODO: if we have further problems, we should investigate passing the
"actual" scene down alongside the "active" scene for BKE_object_handle_update().

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/depsgraph.c
    trunk/blender/source/blender/blenkernel/intern/object.c
    trunk/blender/source/blender/blenkernel/intern/rigidbody.c
    trunk/blender/source/blender/blenkernel/intern/scene.c

Modified: trunk/blender/source/blender/blenkernel/intern/depsgraph.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/depsgraph.c	2013-02-15 11:46:31 UTC (rev 54576)
+++ trunk/blender/source/blender/blenkernel/intern/depsgraph.c	2013-02-15 11:49:22 UTC (rev 54577)
@@ -2353,6 +2353,7 @@
 	if (object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA;
 	if ((ob->pose) && (ob->pose->flag & POSE_CONSTRAINTS_TIMEDEPEND)) ob->recalc |= OB_RECALC_DATA;
 	
+	// XXX: scene here may not be the scene that contains the rigidbody world affecting this!
 	if (ob->rigidbody_object && BKE_scene_check_rigidbody_active(scene))
 		ob->recalc |= OB_RECALC_OB;
 	
@@ -2440,7 +2441,11 @@
 		if (do_time) {
 			/* now if DagNode were part of base, the node->lay could be checked... */
 			/* we do all now, since the scene_flush checks layers and clears recalc flags even */
-			dag_object_time_update_flags(scene, ob);
+			
+			/* NOTE: "sce_iter" not "scene" so that rigidbodies in background scenes work 
+			 * (i.e. muting + rbw availability can be checked and tagged properly) [#33970] 
+			 */
+			dag_object_time_update_flags(sce_iter, ob);
 		}
 
 		/* handled in next loop */

Modified: trunk/blender/source/blender/blenkernel/intern/object.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/object.c	2013-02-15 11:46:31 UTC (rev 54576)
+++ trunk/blender/source/blender/blenkernel/intern/object.c	2013-02-15 11:49:22 UTC (rev 54577)
@@ -2141,7 +2141,8 @@
 	else {
 		BKE_object_to_mat4(ob, ob->obmat);
 	}
-	
+
+	/* read values pushed into RBO from sim/cache... */
 	BKE_rigidbody_sync_transforms(scene, ob, ctime);
 	
 	/* solve constraints */
@@ -2617,6 +2618,11 @@
 
 /* the main object update call, for object matrix, constraints, keys and displist (modifiers) */
 /* requires flags to be set! */
+
+/* WARNING: "scene" here may not be the scene object actually resides in. 
+ * When dealing with background-sets, "scene" is actually the active scene.
+ * e.g. "scene" <-- set 1 <-- set 2 ("ob" lives here) <-- set 3 <-- ... <-- set n
+ */
 void BKE_object_handle_update(Scene *scene, Object *ob)
 {
 	if (ob->recalc & OB_RECALC_ALL) {

Modified: trunk/blender/source/blender/blenkernel/intern/rigidbody.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/rigidbody.c	2013-02-15 11:46:31 UTC (rev 54576)
+++ trunk/blender/source/blender/blenkernel/intern/rigidbody.c	2013-02-15 11:49:22 UTC (rev 54577)
@@ -1136,19 +1136,25 @@
 {
 	RigidBodyWorld *rbw = scene->rigidbody_world;
 	RigidBodyOb *rbo = ob->rigidbody_object;
+	bool world_ok = true;
 
 	/* keep original transform for kinematic and passive objects */
-	if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE)
+	if ((rbo == NULL) || (rbo->flag & RBO_FLAG_KINEMATIC) || (rbo->type == RBO_TYPE_PASSIVE))
 		return;
+		
+	/* "scene" may not be the one where object + rigidbody sim actually reside
+	 * due to the quirks of how background-sets eval works [#33970]
+	 */
+	if (rbw) {
+		/* 1) no cache exists before startframe */
+		/* 2) keep original transform when simulation is muted */
+		world_ok = (ctime > rbw->pointcache->startframe) && !(rbw->flag & RBW_FLAG_MUTED);
+	}
 
 	/* use rigid body transform after cache start frame if objects is not being transformed */
-	if (ctime > rbw->pointcache->startframe && !(ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) {
+	if (world_ok && !((ob->flag & SELECT) && (G.moving & G_TRANSFORM_OBJ))) {
 		float mat[4][4], size_mat[4][4], size[3];
 
-		/* keep original transform when the simulation is muted */
-		if (rbw->flag & RBW_FLAG_MUTED)
-			return;
-
 		normalize_qt(rbo->orn); // RB_TODO investigate why quaternion isn't normalized at this point
 		quat_to_mat4(mat, rbo->orn);
 		copy_v3_v3(mat[3], rbo->pos);
@@ -1165,6 +1171,7 @@
 	}
 }
 
+/* Used when cancelling transforms - return rigidbody and object to initial states */
 void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle)
 {
 	RigidBodyOb *rbo = ob->rigidbody_object;

Modified: trunk/blender/source/blender/blenkernel/intern/scene.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/scene.c	2013-02-15 11:46:31 UTC (rev 54576)
+++ trunk/blender/source/blender/blenkernel/intern/scene.c	2013-02-15 11:49:22 UTC (rev 54577)
@@ -1093,7 +1093,6 @@
 {
 	Base *base;
 	
-	
 	scene->customdata_mask = scene_parent->customdata_mask;
 
 	/* sets first, we allow per definition current scene to have
@@ -1101,6 +1100,23 @@
 	if (scene->set)
 		scene_update_tagged_recursive(bmain, scene->set, scene_parent);
 	
+	/* run rigidbody sim 
+	 * - calculate/read values from cache into RBO's, to get flushed 
+	 *   later when objects are evaluated (if they're tagged for eval)
+	 */
+	// XXX: this position may still change, objects not being updated correctly before simulation is run
+	// NOTE: current position is so that rigidbody sim affects other objects
+	// FIXME: this now gets executed on every update, not just frame change now!!!
+	if (BKE_scene_check_rigidbody_active(scene)) {
+		/* we use frame time of parent (this is "scene" itself for top-level of sets recursion), 
+		 * as that is the active scene controlling all timing in file at the moment
+		 */
+		float ctime = BKE_scene_frame_get(scene_parent);
+		
+		/* however, "scene" contains the rigidbody world needed for eval... */
+		BKE_rigidbody_do_simulation(scene, ctime);
+	}
+	
 	/* scene objects */
 	for (base = scene->base.first; base; base = base->next) {
 		Object *ob = base->object;
@@ -1206,14 +1222,8 @@
 	 * such as Scene->World->MTex/Texture) can still get correctly overridden.
 	 */
 	BKE_animsys_evaluate_all_animation(bmain, sce, ctime);
-	/*...done with recusrive funcs */
+	/*...done with recursive funcs */
 
-	/* run rigidbody sim */
-	// XXX: this position may still change, objects not being updated correctly before simulation is run
-	// NOTE: current position is so that rigidbody sim affects other objects
-	if (BKE_scene_check_rigidbody_active(sce))
-		BKE_rigidbody_do_simulation(sce, ctime);
-
 	/* clear "LIB_DOIT" flag from all materials, to prevent infinite recursion problems later 
 	 * when trying to find materials with drivers that need evaluating [#32017] 
 	 */




More information about the Bf-blender-cvs mailing list