[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [29839] branches/soc-2010-aligorith-2/ source/blender: == Bullet SoC - RNA Fixes + Error Handling ==

Joshua Leung aligorith at gmail.com
Thu Jul 1 12:10:30 CEST 2010


Revision: 29839
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=29839
Author:   aligorith
Date:     2010-07-01 12:10:29 +0200 (Thu, 01 Jul 2010)

Log Message:
-----------
== Bullet SoC - RNA Fixes + Error Handling ==

* Added error checks when trying to add objects to rigidbody sims. These enforce that active objects can only belong in one sim at a time. Also, it warns when an object already exists in the current sim world.

* Added RNA path-building functions so that settings can have keyframes set. For some reason, some settings don't seem to be animating correctly though. Then again, trying to playback again those settings fails too. To be investigated further...

* Added a few helper macros for a few useful situations...

* Removed some unused code

Modified Paths:
--------------
    branches/soc-2010-aligorith-2/source/blender/blenkernel/BKE_rigidbody.h
    branches/soc-2010-aligorith-2/source/blender/blenkernel/intern/rigidbody.c
    branches/soc-2010-aligorith-2/source/blender/editors/physics/rigidbody_object.c
    branches/soc-2010-aligorith-2/source/blender/makesrna/intern/rna_rigidbody.c

Modified: branches/soc-2010-aligorith-2/source/blender/blenkernel/BKE_rigidbody.h
===================================================================
--- branches/soc-2010-aligorith-2/source/blender/blenkernel/BKE_rigidbody.h	2010-07-01 07:13:03 UTC (rev 29838)
+++ branches/soc-2010-aligorith-2/source/blender/blenkernel/BKE_rigidbody.h	2010-07-01 10:10:29 UTC (rev 29839)
@@ -61,9 +61,28 @@
 /* Utilities */
 
 struct RigidBodyWorld *BKE_rigidbody_group_get_world(struct Scene *scene, struct Group *group);
+struct RigidBodyWorld *BKE_rigidbody_object_get_world(struct Scene *scene, struct Object *ob, struct RigidBodyWorld *first_world);
+
 struct RigidBodyWorld *BKE_rigidbody_get_active_world(struct Scene *scene, short add);
 
 /* -------------- */
+/* Utility Macros */
+
+/* looper macro to get every RigidBodyWorld that object occurs in 
+ * < scene: (Scene *) scene containing the Rigid Body Worlds
+ * < ob: (Object *) object that we're trying to find the RigidBodyWorld memberships for
+ * <> rbw: (RigidBodyWorld *) Rigid Body World pointer to a world that involves the object in question
+ */
+#define RB_WORLDS_WITH_OB_LOOPER(scene, ob, rbwPtr) \
+	for (rbwPtr = BKE_rigidbody_object_get_world(scene, ob, NULL); \
+		 rbwPtr != NULL; \
+		 rbwPtr = (rbwPtr->next)? BKE_rigidbody_object_get_world(scene, ob, rbwPtr->next) : NULL)
+
+/* get mass of Rigid Body Object to supply to RigidBody simulators */
+#define RB_OBJECT_GET_MASS(rbo) \
+	((rbo && (rbo->type==RBO_TYPE_ACTIVE))? (rbo->mass) : (0.0f)) 
+
+/* -------------- */
 /* Simulation */
 
 void BKE_rigidbody_do_simulation(struct Scene *scene, struct RigidBodyWorld *rbw, float ctime);

Modified: branches/soc-2010-aligorith-2/source/blender/blenkernel/intern/rigidbody.c
===================================================================
--- branches/soc-2010-aligorith-2/source/blender/blenkernel/intern/rigidbody.c	2010-07-01 07:13:03 UTC (rev 29838)
+++ branches/soc-2010-aligorith-2/source/blender/blenkernel/intern/rigidbody.c	2010-07-01 10:10:29 UTC (rev 29839)
@@ -207,7 +207,6 @@
 void BKE_rigidbody_validate_sim_object (RigidBodyWorld *rbw, Object *ob, short force)
 {
 	RigidBodyOb *rbo = (ob) ? ob->rigidbodySettings : NULL;
-	float mass = 0.0f;
 	
 	/* sanity checks */
 	// TODO: should effectors also be added just like everything else? how will they work?
@@ -228,12 +227,8 @@
 	}
 	
 	/* create new rigidbody object instance */
-	// XXX: mass should be calculated via some helper func to get 0.0 when we don't we want 'static' control
-	if (rbo->type == RBO_TYPE_ACTIVE)
-		mass = rbo->mass;
+	rbo->physics_object = rbBodyNew(rbo->physics_shape, RB_OBJECT_GET_MASS(rbo), ob->obmat);
 	
-	rbo->physics_object = rbBodyNew(rbo->physics_shape, mass, ob->obmat);
-	
 	/* Add the specified RigidBodyOb to the given physics world that object belongs to */
 	if (rbw) {
 		// FIXME: this really doesn't take into account the problems with one object being in multiple sims
@@ -376,6 +371,30 @@
 	return NULL;
 }
 
+/* Get the (first) simulation world that uses a particular object 
+ * < (first_world): optional parameter defining the first simulation world in the scene to search from
+ */
+RigidBodyWorld *BKE_rigidbody_object_get_world (Scene *scene, Object *ob, RigidBodyWorld *first_world)
+{
+	RigidBodyWorld *rbw;
+	
+	/* sanity checks */
+	if ELEM(NULL, scene, ob)
+		return NULL;
+		
+	/* check each sim world, assuming that object can only be in one world at a time */
+	if (first_world == NULL)
+		first_world = scene->rigidbody_worlds.first;
+	
+	for (rbw = first_world; rbw; rbw = rbw->next) {
+		if (object_in_group(ob, rbw->group))
+			return rbw;
+	}
+	
+	/* not found */
+	return NULL;
+}	
+
 /* Get active RigidBody world for the given scene, creating one if needed when 'add' is set 
  * < scene: Scene to find active Rigid Body world for
  * < add: If non-zero, create a new RigidBody world if an active one does not exist 
@@ -430,19 +449,6 @@
 	 */
 }
 
-/* .......... */
-
-static void rigidbody_reset_sim_ob (Object *ob, RigidBodyOb *rbo)
-{
-	const float zero_vec[3] = {0,0,0};
-	
-	/* clear velocities */
-	rbBodySetLinearVelocity(rbo->physics_object, zero_vec);
-	rbBodySetAngularVelocity(rbo->physics_object, zero_vec);
-	
-	// TODO: clear forces too?
-}
-
 /* ------------------ */
 
 /* Run RigidBody simulation for the specified physics world */
@@ -528,10 +534,6 @@
 				/* there are settings, but the object(s) must be rebuilt (i.e. after file-reload) */
 				BKE_rigidbody_validate_sim_object(rbw, ob, 1);
 			}
-			else if (rbw->recalc & RBW_RECALC_RESET) {
-				/* reset simulation internals to allow a fresh run */
-				rigidbody_reset_sim_ob(ob, rbo);
-			}
 			
 			/* update simulation object... */
 			rigidbody_update_sim_ob(ob, rbo);
@@ -574,6 +576,9 @@
 			else
 				printf("\tgroup object invalid %p \n", go->ob);
 		}
+		
+		/* only update ltime here, since ltime is only needed for successful forward timestepping... */
+		rbw->ltime = ctime;
 	}
 	else if (timestep < 0) {
 		printf("\tTODO: read back from motion cache not implemented yet\n");
@@ -590,7 +595,6 @@
 	}
 	
 	/* perform tidy-up actions */
-	rbw->ltime = ctime;
 	rbw->recalc = 0;
 }
 

Modified: branches/soc-2010-aligorith-2/source/blender/editors/physics/rigidbody_object.c
===================================================================
--- branches/soc-2010-aligorith-2/source/blender/editors/physics/rigidbody_object.c	2010-07-01 07:13:03 UTC (rev 29838)
+++ branches/soc-2010-aligorith-2/source/blender/editors/physics/rigidbody_object.c	2010-07-01 10:10:29 UTC (rev 29839)
@@ -42,6 +42,7 @@
 
 #include "BKE_context.h"
 #include "BKE_depsgraph.h"
+#include "BKE_group.h"
 #include "BKE_global.h"
 #include "BKE_main.h"
 #include "BKE_report.h"
@@ -65,15 +66,42 @@
 
 static void ed_rigidbody_ob_add (bContext *C, wmOperator *op, RigidBodyWorld *rbw, Object *ob, int type)
 {
+	Scene *scene = CTX_data_scene(C);
 	RigidBodyOb *rbo;
 	
 	/* check that object doesn't already belong to another group 
 	 * or to the current simulation already
 	 */
 	if (ob->rigidbodySettings) {
-		// 1) already exists in group
-		// 2) may be in the current group (which is fine), but need to check that
-		// 3) otherwise, in another group, which isn't fine, and which we need to warn about if trying to do active
+		rbo = ob->rigidbodySettings;
+		
+		/* if active, it must only be in the active RigidBodyWorld */
+		if (rbo->type == RBO_TYPE_ACTIVE) {
+			/* check what worlds the object is in, and warn if that/those isn't the current world */
+			RigidBodyWorld *rbwP = NULL;
+			short needs_exit = 0;
+			
+			RB_WORLDS_WITH_OB_LOOPER(scene, ob, rbwP)
+			{
+				/* don't go any further after this step, since we've found users already... */
+				needs_exit = 1;
+				
+				if (rbwP != rbw) {
+					BKE_reportf(op->reports, RPT_ERROR, 
+						"Object '%s' is already an active participant in another Rigid Body Simulation",
+						ob->id.name+2);
+				}
+				else {
+					BKE_reportf(op->reports, RPT_INFO, 
+						"Object '%s' already belongs to the current Rigid Body Simulation",
+						ob->id.name+2);
+				}
+			}
+			
+			/* don't go any further if something bad was found */
+			if (needs_exit)
+				return;
+		}
 	}
 	
 	/* make rigidbody object settings */
@@ -83,7 +111,7 @@
 	// TODO...
 	
 	/* actually create the object */
-	BKE_rigidbody_validate_sim_object(rbw, ob, 1);
+	BKE_rigidbody_validate_sim_object(rbw, ob, 0);
 }
 
 static void ed_rigidbody_ob_remove (bContext *C, wmOperator *op, Scene *scene, Object *ob)
@@ -91,18 +119,17 @@
 	RigidBodyWorld *rbw;
 	
 	/* remove object's rigidbody stuff from all worlds */
-	for (rbw = scene->rigidbody_worlds.first; rbw; rbw = rbw->next) {
-		if (object_in_group(ob, rbw->group)) {
-			/* remove from group */
-			rem_from_group(rbw->group, ob, scene, NULL);
-			
-			/* remove object's settings */
-			BKE_rigidbody_free_object(ob);
-		}
+	RB_WORLDS_WITH_OB_LOOPER(scene, ob, rbw)
+	{
+		/* remove from group */
+		rem_from_group(rbw->group, ob, scene, NULL);
+		
+		/* remove object's settings */
+		BKE_rigidbody_free_object(ob);
 	}
 	
 	/* sets recalc flags */
-	DAG_id_flush_update(ob, OB_RECALC);  
+	DAG_id_flush_update(&ob->id, OB_RECALC);  
 }
 
 /* ********************************************** */

Modified: branches/soc-2010-aligorith-2/source/blender/makesrna/intern/rna_rigidbody.c
===================================================================
--- branches/soc-2010-aligorith-2/source/blender/makesrna/intern/rna_rigidbody.c	2010-07-01 07:13:03 UTC (rev 29838)
+++ branches/soc-2010-aligorith-2/source/blender/makesrna/intern/rna_rigidbody.c	2010-07-01 10:10:29 UTC (rev 29839)
@@ -58,6 +58,9 @@
 
 #include "RBI_api.h"
 
+#include "BKE_rigidbody.h"
+
+
 /* ******************************** */
 
 static void rna_RigidBodyWorld_name_get(PointerRNA *ptr, char *value)
@@ -80,8 +83,22 @@
 		return strlen("<Empty World>");
 }
 
+static char *rna_RigidBodyWorld_path(PointerRNA *ptr)
+{	
+	Scene *scene = (Scene *)ptr->id.data;
+	RigidBodyWorld *rbw = (RigidBodyWorld *)ptr->data;
+	
+	return BLI_sprintfN("rigidbody_worlds[%d]", BLI_findindex(&scene->rigidbody_worlds, rbw));
+}
+
 /* ******************************** */
 
+static char *rna_RigidBodyOb_path(PointerRNA *ptr)
+{
+	/* NOTE: this hardcoded path should work as long as only Objects have this */
+	return BLI_sprintfN("rigid_body");
+}
+
 static void rna_RigidBodyOb_type_set(PointerRNA *ptr, int value)
 {
 	RigidBodyOb *rbo = (RigidBodyOb *)ptr->data;
@@ -90,14 +107,8 @@
 	rbo->type = value;
 	
 	/* do physics sim updates */
-	if (rbo->physics_object) {
-		/* 'mass' that gets used by RigidBody depends on type - only dynamic/active RB's have mass */
-		// TODO: abstract this a bit - maybe with a simple macro...
-		if (rbo->type == RBO_TYPE_ACTIVE)
-			rbBodySetMass(rbo->physics_object, rbo->mass);
-		else
-			rbBodySetMass(rbo->physics_object, 0.0f);
-	}
+	if (rbo->physics_object)
+		rbBodySetMass(rbo->physics_object, RB_OBJECT_GET_MASS(rbo));
 }
 
 static void rna_RigidBodyOb_shape_set(PointerRNA *ptr, int value)
@@ -144,6 +155,7 @@
 	srna= RNA_def_struct(brna, "RigidBodyWorld", NULL);
 	RNA_def_struct_sdna(srna, "RigidBodyWorld");
 	RNA_def_struct_ui_text(srna, "Rigid Body World", "Self-contained rigid body simulation environment and settings");
+	RNA_def_struct_path_func(srna, "rna_RigidBodyWorld_path");
 	
 	/* name 
 	 *	- this refers to the name of the associated group only
@@ -196,6 +208,7 @@
 	srna= RNA_def_struct(brna, "RigidBodyObject", NULL);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list