[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58490] branches/soc-2013-rigid_body_sim: rigidbody: Add custom center of mass for primitive shapes

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


Revision: 58490
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58490
Author:   sergof
Date:     2013-07-22 07:20:27 +0000 (Mon, 22 Jul 2013)
Log Message:
-----------
rigidbody: Add custom center of mass for primitive shapes

Now the origin of the object is the center of mass for all collision
shapes.
To do that all shapes are now wrapped inside a compound shape.

TODO: fix istability with mesh shapes when using compounds, might be
bullet bug.

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/rigidbody.c

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:14:25 UTC (rev 58489)
+++ branches/soc-2013-rigid_body_sim/intern/rigidbody/RBI_api.h	2013-07-22 07:20:27 UTC (rev 58490)
@@ -214,11 +214,11 @@
 
 /* Setup (Standard Shapes) ----------- */
 
-extern rbCollisionShape *RB_shape_new_box(float x, float y, float z);
-extern rbCollisionShape *RB_shape_new_sphere(float radius);
-extern rbCollisionShape *RB_shape_new_capsule(float radius, float height);
-extern rbCollisionShape *RB_shape_new_cone(float radius, float height);
-extern rbCollisionShape *RB_shape_new_cylinder(float radius, float height);
+extern rbCollisionShape *RB_shape_new_box(float x, float y, float z, const float loc[3], const float rot[4], const float center[3]);
+extern rbCollisionShape *RB_shape_new_sphere(float radius, const float loc[3], const float rot[4], const float center[3]);
+extern rbCollisionShape *RB_shape_new_capsule(float radius, float height, const float loc[3], const float rot[4], const float center[3]);
+extern rbCollisionShape *RB_shape_new_cone(float radius, float height, const float loc[3], const float rot[4], const float center[3]);
+extern rbCollisionShape *RB_shape_new_cylinder(float radius, float height, const float loc[3], const float rot[4], const float center[3]);
 
 /* Setup (Convex Hull) ------------ */
 

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:14:25 UTC (rev 58489)
+++ branches/soc-2013-rigid_body_sim/intern/rigidbody/rb_bullet_api.cpp	2013-07-22 07:20:27 UTC (rev 58490)
@@ -89,6 +89,7 @@
 
 struct rbCollisionShape {
 	btCollisionShape *cshape;
+	btCollisionShape *compound;
 	btTriangleMesh *mesh;
 };
 
@@ -367,7 +368,7 @@
 	btDefaultMotionState *motionState = new btDefaultMotionState(trans);
 	
 	/* make rigidbody */
-	btRigidBody::btRigidBodyConstructionInfo rbInfo(1.0f, motionState, shape->cshape);
+	btRigidBody::btRigidBodyConstructionInfo rbInfo(1.0f, motionState, shape->compound);
 	
 	object->body = new btRigidBody(rbInfo);
 	
@@ -407,7 +408,7 @@
 	btRigidBody *body = object->body;
 	
 	/* set new collision shape */
-	body->setCollisionShape(shape->cshape);
+	body->setCollisionShape(shape->compound);
 	
 	/* recalculate inertia, since that depends on the collision shape... */
 	RB_body_set_mass(object, RB_body_get_mass(object));
@@ -685,46 +686,55 @@
 
 /* Setup (Standard Shapes) ----------- */
 
-rbCollisionShape *RB_shape_new_box(float x, float y, float z)
+static rbCollisionShape *prepare_primitive_shape(btCollisionShape *cshape, const float loc[3], const float rot[4], const float center[3])
 {
 	rbCollisionShape *shape = new rbCollisionShape;
-	shape->cshape = new btBoxShape(btVector3(x, y, z));
+	shape->cshape = cshape;
 	shape->mesh = NULL;
+	
+	btTransform world_transform = btTransform();
+	world_transform.setIdentity();
+	world_transform.setOrigin(btVector3(loc[0], loc[1], loc[2]));
+	world_transform.setRotation(btQuaternion(rot[1], rot[2], rot[3], rot[0]));
+	
+	shape->compound = new btCompoundShape();
+	btTransform compound_transform;
+	compound_transform.setIdentity();
+	/* adjust center of mass */
+	compound_transform.setOrigin(btVector3(center[0], center[1], center[2]));
+	compound_transform.setRotation(btQuaternion(rot[1], rot[2], rot[3], rot[0]));
+	compound_transform = world_transform.inverse() * compound_transform;
+	
+	((btCompoundShape*)shape->compound)->addChildShape(compound_transform, shape->cshape);
+	
 	return shape;
 }
 
-rbCollisionShape *RB_shape_new_sphere(float radius)
+rbCollisionShape *RB_shape_new_box(float x, float y, float z, const float loc[3], const float rot[4], const float center[3])
 {
-	rbCollisionShape *shape = new rbCollisionShape;
-	shape->cshape = new btSphereShape(radius);
-	shape->mesh = NULL;
-	return shape;
+	return prepare_primitive_shape(new btBoxShape(btVector3(x, y, z)), loc, rot, center);
 }
 
-rbCollisionShape *RB_shape_new_capsule(float radius, float height)
+rbCollisionShape *RB_shape_new_sphere(float radius, const float loc[3], const float rot[4], const float center[3])
 {
-	rbCollisionShape *shape = new rbCollisionShape;
-	shape->cshape = new btCapsuleShapeZ(radius, height);
-	shape->mesh = NULL;
-	return shape;
+	return prepare_primitive_shape(new btSphereShape(radius), loc, rot, center);
 }
 
-rbCollisionShape *RB_shape_new_cone(float radius, float height)
+rbCollisionShape *RB_shape_new_capsule(float radius, float height, const float loc[3], const float rot[4], const float center[3])
 {
-	rbCollisionShape *shape = new rbCollisionShape;
-	shape->cshape = new btConeShapeZ(radius, height);
-	shape->mesh = NULL;
-	return shape;
+	return prepare_primitive_shape(new btCapsuleShapeZ(radius, height), loc, rot, center);
 }
 
-rbCollisionShape *RB_shape_new_cylinder(float radius, float height)
+rbCollisionShape *RB_shape_new_cone(float radius, float height, const float loc[3], const float rot[4], const float center[3])
 {
-	rbCollisionShape *shape = new rbCollisionShape;
-	shape->cshape = new btCylinderShapeZ(btVector3(radius, radius, height));
-	shape->mesh = NULL;
-	return shape;
+	return prepare_primitive_shape(new btConeShapeZ(radius, height), loc, rot, center);
 }
 
+rbCollisionShape *RB_shape_new_cylinder(float radius, float height, const float loc[3], const float rot[4], const float center[3])
+{
+	return prepare_primitive_shape(new btCylinderShapeZ(btVector3(radius, radius, height)), loc, rot, center);
+}
+
 /* Setup (Convex Hull) ------------ */
 
 rbCollisionShape *RB_shape_new_convex_hull(float *verts, int stride, int count, float margin, bool *can_embed)
@@ -789,6 +799,12 @@
 	
 	shape->cshape = new btScaledBvhTriangleMeshShape(unscaledShape, btVector3(1.0f, 1.0f, 1.0f));
 	shape->mesh = tmesh;
+	
+	shape->compound = new btCompoundShape();
+	btTransform compound_transform;
+	compound_transform.setIdentity();
+	((btCompoundShape*)shape->compound)->addChildShape(compound_transform, shape->cshape);
+	
 	return shape;
 }
 
@@ -818,6 +834,7 @@
 	if (shape->mesh)
 		delete shape->mesh;
 	delete shape->cshape;
+	delete shape->compound;
 	delete shape;
 }
 

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:14:25 UTC (rev 58489)
+++ branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/rigidbody.c	2013-07-22 07:20:27 UTC (rev 58490)
@@ -355,6 +355,8 @@
 	rbCollisionShape *new_shape = NULL;
 	BoundBox *bb = NULL;
 	float size[3] = {1.0f, 1.0f, 1.0f};
+	float center[3], min[3], max[3];
+	float loc[3], rot[4];
 	float radius = 1.0f;
 	float height = 1.0f;
 	float capsule_height;
@@ -395,25 +397,33 @@
 		radius = MAX3(size[0], size[1], size[2]);
 	}
 
+	mat4_to_loc_quat(loc, rot, ob->obmat);
+
+	/* calculate world space center of object */
+	mul_v3_m4v3(min, ob->obmat, bb->vec[0]);
+	mul_v3_m4v3(max, ob->obmat, bb->vec[6]);
+	add_v3_v3v3(center, max, min);
+	mul_v3_fl(center, 0.5f);
+
 	/* create new shape */
 	switch (rbo->shape) {
 		case RB_SHAPE_BOX:
-			new_shape = RB_shape_new_box(size[0], size[1], size[2]);
+			new_shape = RB_shape_new_box(size[0], size[1], size[2], loc, rot, center);
 			break;
 
 		case RB_SHAPE_SPHERE:
-			new_shape = RB_shape_new_sphere(radius);
+			new_shape = RB_shape_new_sphere(radius, loc, rot, center);
 			break;
 
 		case RB_SHAPE_CAPSULE:
 			capsule_height = (height - radius) * 2.0f;
-			new_shape = RB_shape_new_capsule(radius, (capsule_height > 0.0f) ? capsule_height : 0.0f);
+			new_shape = RB_shape_new_capsule(radius, (capsule_height > 0.0f) ? capsule_height : 0.0f, loc, rot, center);
 			break;
 		case RB_SHAPE_CYLINDER:
-			new_shape = RB_shape_new_cylinder(radius, height);
+			new_shape = RB_shape_new_cylinder(radius, height, loc, rot, center);
 			break;
 		case RB_SHAPE_CONE:
-			new_shape = RB_shape_new_cone(radius, height * 2.0f);
+			new_shape = RB_shape_new_cone(radius, height * 2.0f, loc, rot, center);
 			break;
 
 		case RB_SHAPE_CONVEXH:




More information about the Bf-blender-cvs mailing list