[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [29814] branches/soc-2010-aligorith-2/ source/blender: == Bullet SoC - Collisions and More ==

Joshua Leung aligorith at gmail.com
Wed Jun 30 07:21:09 CEST 2010


Revision: 29814
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=29814
Author:   aligorith
Date:     2010-06-30 07:21:08 +0200 (Wed, 30 Jun 2010)

Log Message:
-----------
== Bullet SoC - Collisions and More ==

Collision Shapes now work properly:
* Fixed implementation of Box and Sphere types so that they result in actual collisions. They were using the full dimensions instead of the distance from the boundbox corners to the center of mass. Now, these calculations assume centered distributions of mass (i.e. pivot is not off to one side of the object)
* Implemented Capsule, Cylinder, and Cone types too while I was at it. 'Mesh' type will have to wait a while, but will be available eventually (more API work needed first) :)
* By default, collision shapes are now automatically set to the most appropriate type based on the type of bounding-box shown for the object (i.e. see 'bounds' setting)
* The 'Shape' property also now works. I've hooked this up so that it can now be changed. As side effect, you can also animate this :)

Improved Blender-Side API's:
* Made the calls to create physics-sim data able to be called outside of rigidbody.c
* Cleaned up some code in preparation for motion-cache support

Playback Bugfix:
* Resetting sims now works properly. 
-- The problem was that objects were not being recalculated on frame changes (missing depsgraph code. More depsgraph changes will still be needed for other things later...). 
-- Also, this is now done by fully refreshing all sim objects instead of trying to get away with resetting some settings, avoiding some internal vars being outdated still.

Modified Paths:
--------------
    branches/soc-2010-aligorith-2/source/blender/blenkernel/BKE_rigidbody.h
    branches/soc-2010-aligorith-2/source/blender/blenkernel/intern/depsgraph.c
    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
    branches/soc-2010-aligorith-2/source/blender/rigidbody/RBI_api.h

Modified: branches/soc-2010-aligorith-2/source/blender/blenkernel/BKE_rigidbody.h
===================================================================
--- branches/soc-2010-aligorith-2/source/blender/blenkernel/BKE_rigidbody.h	2010-06-30 05:03:41 UTC (rev 29813)
+++ branches/soc-2010-aligorith-2/source/blender/blenkernel/BKE_rigidbody.h	2010-06-30 05:21:08 UTC (rev 29814)
@@ -42,15 +42,20 @@
 
 void BKE_rigidbody_free_world(struct Scene *scene, struct RigidBodyWorld *rbw);
 void BKE_rigidbody_free_worlds(struct Scene *scene);
+
 void BKE_rigidbody_free_object(struct Scene *scene, struct Object *ob);
 
 /* -------------- */
 /* Setup */
 
-struct RigidBodyWorld *BKE_rigidbody_make_world(struct Scene *scene, struct Group *group);
-struct RigidBodyOb *BKE_rigidbody_make_object(struct RigidBodyWorld *rbw, struct Object *ob);
+/* create Blender-side settings data - physics objects not initialised yet */
+struct RigidBodyWorld *BKE_rigidbody_create_world(struct Scene *scene, struct Group *group);
+struct RigidBodyOb *BKE_rigidbody_create_object(struct RigidBodyWorld *rbw, struct Object *ob, short type);
 
-void BKE_rigidbody_update_object(struct RigidBodyWorld *rbw, struct Object *ob);
+/* 'validate' (i.e. make new or replace old) Physics-Engine objects */
+void BKE_rigidbody_validate_sim_world(struct Scene *scene, struct RigidBodyWorld *rbw, short force);
+void BKE_rigidbody_validate_sim_object(struct RigidBodyWorld *rbw, struct Object *ob, short force);
+void BKE_rigidbody_validate_sim_shape(struct Object *ob, short force);
 
 /* -------------- */
 /* Utilities */

Modified: branches/soc-2010-aligorith-2/source/blender/blenkernel/intern/depsgraph.c
===================================================================
--- branches/soc-2010-aligorith-2/source/blender/blenkernel/intern/depsgraph.c	2010-06-30 05:03:41 UTC (rev 29813)
+++ branches/soc-2010-aligorith-2/source/blender/blenkernel/intern/depsgraph.c	2010-06-30 05:21:08 UTC (rev 29814)
@@ -37,6 +37,7 @@
 #include "DNA_lattice_types.h"
 #include "DNA_key_types.h"
 #include "DNA_mesh_types.h"
+#include "DNA_rigidbody_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_windowmanager_types.h"
@@ -56,6 +57,7 @@
 #include "BKE_object.h"
 #include "BKE_particle.h"
 #include "BKE_pointcache.h"
+#include "BKE_rigidbody.h"
 #include "BKE_scene.h"
 #include "BKE_screen.h"
 
@@ -2042,6 +2044,8 @@
 	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;
 	
+	if(ob->rigidbodySettings) ob->recalc |= OB_RECALC;
+	
 	{
 		AnimData *adt= BKE_animdata_from_id((ID *)ob->data);
 		Mesh *me;

Modified: branches/soc-2010-aligorith-2/source/blender/blenkernel/intern/rigidbody.c
===================================================================
--- branches/soc-2010-aligorith-2/source/blender/blenkernel/intern/rigidbody.c	2010-06-30 05:03:41 UTC (rev 29813)
+++ branches/soc-2010-aligorith-2/source/blender/blenkernel/intern/rigidbody.c	2010-06-30 05:21:08 UTC (rev 29814)
@@ -36,6 +36,7 @@
 #include "MEM_guardedalloc.h"
 
 #include "BLI_blenlib.h"
+#include "BLI_math.h"
 
 #include "RBI_api.h"
 
@@ -125,34 +126,68 @@
 }
 
 /* ************************************** */
-/* Setup Utilities */
+/* Setup Utilities - Validate Sim Instances */
 
-/* Create new physics sim collision shape for object, and store it */
-static void rigidbody_validate_sim_shape (Object *ob, RigidBodyOb *rbo)
+/* Create new physics sim collision shape for object and store it,
+ * or remove the existing one first and replace...
+ */
+void BKE_rigidbody_validate_sim_shape (Object *ob, short force)
 {
-	// XXX: testing code for setting up box and sphere collision shapes. Quick initial prototype only!
-	float dims[3];
-	object_get_dimensions(ob, dims);
+	RigidBodyOb *rbo = ob->rigidbodySettings;
+	float size[3] = {1.0f, 1.0f, 1.0f};
+	float radius = 1.0f;
+	float height = 1.0f;
 	
-	/* shape to create depends on type */
+	/* sanity check */
+	if (rbo == NULL)
+		return;
+	
+	/* check if existing instance exists */
+	if (rbo->physics_shape) {
+		/* get rid of it and rebuild? */
+		if (force)
+			rbShapeDelete(rbo->physics_shape);
+		else	
+			return;
+	}
+	
+	/* if automatically determining dimensions, use the Object's boundbox
+	 *	- assume that all quadrics are standing upright on local z-axis
+	 *	- assume even distribution of mass around the Object's pivot 
+	 *	  (i.e. Object pivot is centralised in boundbox)
+	 */
+	// XXX: all dimensions are auto-determined now... later can add stored settings for this
+	object_get_dimensions(ob, size);
+	mul_v3_fl(size, 0.5f);
+	
+	if (ELEM3(rbo->shape, RB_SHAPE_CAPSULE, RB_SHAPE_CYLINDER, RB_SHAPE_CONE)) {
+		/* take radius as largest x/y dimension, and height as z-dimension */
+		radius = MAX2(size[0], size[1]);
+		height = size[2];
+	}
+	else if (rbo->shape == RB_SHAPE_SPHERE) {
+		/* take radius to the the largest dimension to try and encompass everything */
+		radius = MAX2(size[0], MAX2(size[1], size[2]));
+	}
+	
+	/* create new shape */
 	switch (rbo->shape) {
-		case RB_SHAPE_BOX: // includes ground planes...
-			// just take the bounding box dimensions per axis...
-			// XXX: do we need to switch y and z due to diff coordinate systems being used?
-			rbo->physics_shape = rbShapeNewBox(dims[0], dims[1], dims[2]);
+		case RB_SHAPE_BOX:
+			rbo->physics_shape = rbShapeNewBox(size[0], size[1], size[2]);
 			break;
+			
 		case RB_SHAPE_SPHERE:
-			// just take the maximum bounding box dimension to fit everything
-			rbo->physics_shape = rbShapeNewSphere(MAX2(dims[0], MAX2(dims[1], dims[2])));
+			rbo->physics_shape = rbShapeNewSphere(radius);
 			break;
-			
-		// XXX: figure out how to implement these later...
-		// 	- might need to add extra parameters to determine the shapes of these
+		
 		case RB_SHAPE_CAPSULE:
+			rbo->physics_shape = rbShapeNewCapsule(radius, height);
 			break;
 		case RB_SHAPE_CYLINDER:
+			rbo->physics_shape = rbShapeNewCylinder(radius, height);
 			break;
 		case RB_SHAPE_CONE:
+			rbo->physics_shape = rbShapeNewCone(radius, height);
 			break;
 		
 		case RB_SHAPE_TRIMESH:
@@ -162,19 +197,26 @@
 	}
 }
 
+
 /* --------------------- */
 
 /* Create physics sim representation of object given RigidBody settings 
- * < rbo: RigidBody Object settings to add sim object for
  * < force: even if an instance already exists, replace it
  */
-static void rigidbody_validate_sim_ob (Object *ob, RigidBodyOb *rbo, short force)
+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?
 	if (rbo == NULL)
 		return;
 	
+	/* make sure collision shape exists */
+	if ((rbo->physics_shape == NULL) || (force)) 
+		BKE_rigidbody_validate_sim_shape(ob, force);
+	
 	/* check if existing instance exists */
 	if (rbo->physics_object) {
 		/* get rid of it and rebuild? */
@@ -184,48 +226,50 @@
 			return;
 	}
 	
-	/* make sure collision shape exists */
-	if ((rbo->physics_shape == NULL) || (force)) {
-		/* remove existing shape for good measure, then build new one */
-		rbShapeDelete(rbo->physics_shape);
-		rigidbody_validate_sim_shape(ob, rbo);
-	}
-	
 	/* 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
-	rbo->physics_object = rbBodyNew(rbo->physics_shape, rbo->mass, ob->obmat);
+	if (rbo->type == RBO_TYPE_ACTIVE)
+		mass = rbo->mass;
+	
+	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
+		// at once... that will need further work later...
+		rbDWorldAddBody(rbw->physics_world, rbo->physics_object);
+	}
 }	
 
-/* Add the specified RigidBodyOb to the given physics world */
-static void rigidbody_add_sim_ob (RigidBodyWorld *rbw, RigidBodyOb *rbo)
-{
-	// FIXME: this really doesn't take into account the problems with one object being in multiple sims
-	// at once... that will need further work later...
-	rbDWorldAddBody(rbw->physics_world, rbo->physics_object);
-}
-
 /* --------------------- */
 
 /* Create physics sim world given RigidBody world settings */
 // NOTE: this does NOT update object references that the scene uses, in case those aren't ready yet!
-static void rigidbody_validate_sim_world (Scene *scene, RigidBodyWorld *rbw)
+void BKE_rigidbody_validate_sim_world (Scene *scene, RigidBodyWorld *rbw, short force)
 {
 	/* sanity checks */
 	if (rbw == NULL)
 		return;
 		
-	/* if there's an existing world, replace it */
-	if (rbw->physics_world) 
-		rbDWorldDelete(rbw->physics_world);
-		
+	/* check if existing instance exists */
+	if (rbw->physics_world) {
+		/* get rid of it and rebuild? */
+		if (force)
+			rbDWorldDelete(rbw->physics_world);
+		else
+			return;
+	}
+	
 	/* create new sim world */
+	// TODO: set other settings too?
 	rbw->physics_world = rbDWorldCreate(scene->physics_settings.gravity);
 }
 
-/* --------------------- */
+/* ************************************** */
+/* Setup Utilities - Create Settings Blocks */
 
 /* Set up RigidBody world */
-RigidBodyWorld *BKE_rigidbody_make_world (Scene *scene, Group *group)
+RigidBodyWorld *BKE_rigidbody_create_world (Scene *scene, Group *group)
 {
 	/* try to get whatever RigidBody world that might be representing this already */
 	RigidBodyWorld *rbw = BKE_rigidbody_group_get_world(scene, group);
@@ -248,18 +292,35 @@
 	rbw->sframe = PSFRA;
 	
 	// XXX: review these
-	rbw->max_timestep = 10;
-	rbw->substeps = 5;
+	rbw->max_timestep = 1.0f;
+	rbw->substeps = 10;
 	
-	/* make sure sim world is set up ok... */
-	rigidbody_validate_sim_world(scene, rbw);
-	
 	/* return this sim world */
 	return rbw;
 }
 
+
+/* helper for BKE_rigidbody_create_object() - determines the collision shape from the boundbox type */
+// TODO: should we just use the ob->boundbox setting instead to make life easier?
+static int get_shape_from_boundbox (Object *ob)
+{
+	switch (ob->boundtype) {
+		case OB_BOUND_BOX:
+			return RB_SHAPE_BOX;
+		case OB_BOUND_SPHERE:
+			return RB_SHAPE_SPHERE;
+		case OB_BOUND_CYLINDER:
+			return RB_SHAPE_CYLINDER;
+		case OB_BOUND_CONE:

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list