[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58492] branches/soc-2013-rigid_body_sim: rigidbody: Add support for compound shapes

Sergej Reich sergej.reich at googlemail.com
Mon Jul 22 09:20:30 CEST 2013


Revision: 58492
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58492
Author:   sergof
Date:     2013-07-22 07:20:30 +0000 (Mon, 22 Jul 2013)
Log Message:
-----------
rigidbody: Add support for compound shapes

Compounds are defined implicitly by the parenting hierarchy.

TODO: Take more one level of the hierarchy is taken into account when
creating compound shapes.

Modified Paths:
--------------
    branches/soc-2013-rigid_body_sim/intern/rigidbody/RBI_api.h
    branches/soc-2013-rigid_body_sim/intern/rigidbody/rb_bullet_api.cpp
    branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/pointcache.c
    branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/rigidbody.c
    branches/soc-2013-rigid_body_sim/source/blender/makesdna/DNA_rigidbody_types.h

Modified: branches/soc-2013-rigid_body_sim/intern/rigidbody/RBI_api.h
===================================================================
--- branches/soc-2013-rigid_body_sim/intern/rigidbody/RBI_api.h	2013-07-22 07:20:28 UTC (rev 58491)
+++ branches/soc-2013-rigid_body_sim/intern/rigidbody/RBI_api.h	2013-07-22 07:20:30 UTC (rev 58492)
@@ -205,6 +205,10 @@
 /* Get RigidBody's orientation as quaternion */
 void RB_body_get_orientation(rbRigidBody *body, float v_out[4]);
 
+void RB_body_get_compound_position(rbRigidBody *object, rbCollisionShape *child_shape, float v_out[3]);
+
+void RB_body_get_compound_orientation(rbRigidBody *object, rbCollisionShape *child_shape, float v_out[4]);
+
 /* ............ */
 
 extern void RB_body_apply_central_force(rbRigidBody *body, const float v_in[3]);
@@ -234,7 +238,10 @@
 /* 2b - GImpact Meshes */
 extern rbCollisionShape *RB_shape_new_gimpact_mesh(rbMeshData *mesh);
 
+/* Compound Shapes ------------------- */
+extern void RB_shape_add_compound_child(rbRigidBody *parent, rbCollisionShape *child, float child_pos[3], float child_orn[4]);
 
+
 /* Cleanup --------------------------- */
 
 extern void RB_shape_delete(rbCollisionShape *shape);

Modified: branches/soc-2013-rigid_body_sim/intern/rigidbody/rb_bullet_api.cpp
===================================================================
--- branches/soc-2013-rigid_body_sim/intern/rigidbody/rb_bullet_api.cpp	2013-07-22 07:20:28 UTC (rev 58491)
+++ branches/soc-2013-rigid_body_sim/intern/rigidbody/rb_bullet_api.cpp	2013-07-22 07:20:30 UTC (rev 58492)
@@ -671,6 +671,44 @@
 	copy_quat_btquat(v_out, body->getWorldTransform().getRotation());
 }
 
+void RB_body_get_compound_position(rbRigidBody *object, rbCollisionShape *child_shape, float v_out[3])
+{
+	btRigidBody *body = object->body;
+	btCompoundShape *compound = (btCompoundShape*)body->getCollisionShape();
+	btTransform transform = body->getWorldTransform();
+	btTransform child_transform;
+	
+	for (int i = 0; i < compound->getNumChildShapes(); i++) {
+		if (child_shape->compound == compound->getChildShape(i)) {
+			child_transform = compound->getChildTransform(i);
+			break;
+		}
+	}
+	transform *= child_transform;
+	btVector3 pos = transform.getOrigin();;
+	
+	copy_v3_btvec3(v_out, pos);
+}
+
+void RB_body_get_compound_orientation(rbRigidBody *object, rbCollisionShape *child_shape, float v_out[4])
+{
+	btRigidBody *body = object->body;
+	btCompoundShape *compound = (btCompoundShape*)body->getCollisionShape();
+	btTransform transform = body->getWorldTransform();
+	btTransform child_transform;
+	
+	for (int i = 0; i < compound->getNumChildShapes(); i++) {
+		if (child_shape->compound == compound->getChildShape(i)) {
+			child_transform = compound->getChildTransform(i);
+			break;
+		}
+	}
+	transform *= child_transform;
+	btQuaternion orn = transform.getRotation();
+	
+	copy_quat_btquat(v_out, orn);
+}
+
 /* ............ */
 /* Overrides for simulation */
 
@@ -828,6 +866,17 @@
 	return shape;
 }
 
+void RB_shape_add_compound_child(rbRigidBody *parent, rbCollisionShape *child, float child_pos[3], float child_orn[4])
+{
+	btCompoundShape *compound = (btCompoundShape*)parent->body->getCollisionShape();
+	btTransform parent_transform = parent->body->getCenterOfMassTransform(); // TODO center of mass?
+	btTransform transform;
+	transform.setOrigin(btVector3(child_pos[0], child_pos[1], child_pos[2]));
+	transform.setRotation(btQuaternion(child_orn[1], child_orn[2], child_orn[3], child_orn[0]));
+	transform = parent_transform.inverse() * transform;
+	compound->addChildShape(transform, child->compound);
+}
+
 /* Cleanup --------------------------- */
 
 void RB_shape_delete(rbCollisionShape *shape)

Modified: branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/pointcache.c
===================================================================
--- branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/pointcache.c	2013-07-22 07:20:28 UTC (rev 58491)
+++ branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/pointcache.c	2013-07-22 07:20:30 UTC (rev 58492)
@@ -976,8 +976,14 @@
 		
 		if (rbo->type == RBO_TYPE_ACTIVE) {
 #ifdef WITH_BULLET
-			RB_body_get_position(rbo->physics_object, rbo->pos);
-			RB_body_get_orientation(rbo->physics_object, rbo->orn);
+			if (ob->parent && ob->parent->rigidbody_object && ob->parent->flag) {
+				RB_body_get_compound_position(ob->parent->rigidbody_object->physics_object, rbo->physics_shape, rbo->pos);
+				RB_body_get_compound_orientation(ob->parent->rigidbody_object->physics_object, rbo->physics_shape, rbo->orn);
+			}
+			else {
+				RB_body_get_position(rbo->physics_object, rbo->pos);
+				RB_body_get_orientation(rbo->physics_object, rbo->orn);
+			}
 #endif
 			PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, rbo->pos);
 			PTCACHE_DATA_FROM(data, BPHYS_DATA_ROTATION, rbo->orn);

Modified: branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/rigidbody.c
===================================================================
--- branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/rigidbody.c	2013-07-22 07:20:28 UTC (rev 58491)
+++ branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/rigidbody.c	2013-07-22 07:20:30 UTC (rev 58492)
@@ -346,6 +346,58 @@
 	return shape;
 }
 
+/* check parent child relationships to construct compound shapes */
+static void rigidbody_prepare_compounds(RigidBodyWorld *rbw)
+{
+	GroupObject *go;
+	for (go = rbw->group->gobject.first; go; go = go->next) {
+		Object *ob = go->ob;
+		RigidBodyOb *rbo = ob ? ob->rigidbody_object : NULL;
+		if (rbo == NULL)
+			continue;
+
+		if (ob->parent && ob->parent->rigidbody_object) {
+			rbo->flag |= RBO_FLAG_COMPOUND_CHILD;
+			ob->parent->rigidbody_object->flag |= RBO_FLAG_COMPOUND_PARENT;
+		}
+	}
+}
+
+/* note, object must be a compound shape parent */
+static void rigidbody_compound_shape_add_children(RigidBodyWorld *rbw, Object *ob)
+{
+	GroupObject *go;
+
+	RigidBodyOb *rbo = ob->rigidbody_object;
+	if (rbo == NULL)
+		return;
+
+	// RB_TODO check entire parent hirarchy not only one level.
+	for (go = rbw->group->gobject.first; go; go = go->next) {
+		Object *child_ob = go->ob;
+		RigidBodyOb *child_rbo = child_ob ? child_ob->rigidbody_object : NULL;
+
+		if (child_rbo && child_rbo->flag & RBO_FLAG_COMPOUND_CHILD) {
+			if (child_ob->parent == ob) {
+				float pos[3], orn[4];
+				mat4_to_loc_quat(pos, orn, child_ob->obmat);
+				RB_shape_add_compound_child(rbo->physics_object, child_rbo->physics_shape, pos, orn);
+			}
+		}
+	}
+}
+
+static void rigidbody_update_compounds(RigidBodyWorld *rbw)
+{
+	GroupObject *go;
+	for (go = rbw->group->gobject.first; go; go = go->next) {
+		Object *ob = go->ob;
+		RigidBodyOb *rbo = ob ? ob->rigidbody_object : NULL;
+		if (rbo && rbo->flag & RBO_FLAG_COMPOUND_PARENT)
+			rigidbody_compound_shape_add_children(rbw, ob);
+	}
+}
+
 /* Create new physics sim collision shape for object and store it,
  * or remove the existing one first and replace...
  */
@@ -513,7 +565,7 @@
 		RB_body_set_kinematic_state(rbo->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
 	}
 
-	if (rbw && rbw->physics_world)
+	if (rbw && rbw->physics_world && (rbo->flag & RBO_FLAG_COMPOUND_CHILD) == 0) // RB_TODO find better solution for compound shapes
 		RB_dworld_add_body(rbw->physics_world, rbo->physics_object, rbo->col_groups);
 }
 
@@ -1096,8 +1148,11 @@
 	if (rebuild)
 		BKE_rigidbody_validate_sim_world(scene, rbw, true);
 	rigidbody_update_sim_world(scene, rbw);
-
+	
 	/* update objects */
+	if (rebuild)
+		rigidbody_prepare_compounds(rbw);
+	
 	for (go = rbw->group->gobject.first; go; go = go->next) {
 		Object *ob = go->ob;
 
@@ -1142,6 +1197,10 @@
 			rigidbody_update_sim_ob(scene, rbw, ob, rbo);
 		}
 	}
+	
+	if (rebuild)
+		rigidbody_update_compounds(rbw);
+	
 	/* update constraints */
 	if (rbw->constraints == NULL) /* no constraints, move on */
 		return;

Modified: branches/soc-2013-rigid_body_sim/source/blender/makesdna/DNA_rigidbody_types.h
===================================================================
--- branches/soc-2013-rigid_body_sim/source/blender/makesdna/DNA_rigidbody_types.h	2013-07-22 07:20:28 UTC (rev 58491)
+++ branches/soc-2013-rigid_body_sim/source/blender/makesdna/DNA_rigidbody_types.h	2013-07-22 07:20:30 UTC (rev 58492)
@@ -148,7 +148,10 @@
 	/* rigidbody is not dynamically simulated */
 	RBO_FLAG_DISABLED			= (1 << 5),
 	/* collision margin is not embedded (only used by convex hull shapes for now) */
-	RBO_FLAG_USE_MARGIN			= (1 << 6)
+	RBO_FLAG_USE_MARGIN			= (1 << 6),
+	/* compound shape flags, should not be set manually */
+	RBO_FLAG_COMPOUND_PARENT	= (1 << 7),
+	RBO_FLAG_COMPOUND_CHILD		= (1 << 8)
 } eRigidBodyOb_Flag;
 
 /* RigidBody Collision Shape */




More information about the Bf-blender-cvs mailing list