[Bf-blender-cvs] [c8bf0aa] temp_bullet_ghosts: Refactoring internal btCollisionShape storage in the rbCollisionShape wrapper class.

Lukas Tönne noreply at git.blender.org
Wed Apr 29 09:08:04 CEST 2015


Commit: c8bf0aa5c4146d2b01a19510df9ed3329ad96826
Author: Lukas Tönne
Date:   Thu Jan 1 15:05:35 2015 +0100
Branches: temp_bullet_ghosts
https://developer.blender.org/rBc8bf0aa5c4146d2b01a19510df9ed3329ad96826

Refactoring internal btCollisionShape storage in the rbCollisionShape
wrapper class.

Now there are a matching subclasses of `rbCollisionShape` for each of
the used `btCollisionShape` equivalents. They store a bt shapes as
direct members, which means the internal memory allocation can be
largely avoided later, which is useful for efficient creation of many
shapes in mempools etc.

===================================================================

M	intern/rigidbody/RBI_api.h
M	intern/rigidbody/rb_bullet_api.cpp

===================================================================

diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h
index 1928230..b407e01 100644
--- a/intern/rigidbody/RBI_api.h
+++ b/intern/rigidbody/RBI_api.h
@@ -254,6 +254,7 @@ rbCollisionShape *RB_shape_new_convex_hull(float *verts, int stride, int count,
 
 /* 1 */
 rbMeshData *RB_trimesh_data_new(int num_tris, int num_verts);
+void RB_trimesh_data_delete(rbMeshData *mesh);
 void RB_trimesh_add_vertices(rbMeshData *mesh, float *vertices, int num_verts, int vert_stride);
 void RB_trimesh_add_triangle_indices(rbMeshData *mesh, int num, int index0, int index1, int index2);
 void RB_trimesh_finish(rbMeshData *mesh);
diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp
index de9f7bb..c1d170d 100644
--- a/intern/rigidbody/rb_bullet_api.cpp
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -114,10 +114,122 @@ struct rbMeshData {
 };
 
 struct rbCollisionShape {
-	btCollisionShape *cshape;
+	virtual ~rbCollisionShape()
+	{}
+	
+	virtual btCollisionShape *get_cshape() = 0;
+};
+
+struct rbBoxShape : public rbCollisionShape {
+	rbBoxShape(float x, float y, float z) :
+		cshape(btVector3(x, y, z))
+	{}
+	
+	btBoxShape cshape;
+	btCollisionShape *get_cshape() { return &cshape; }
+};
+
+struct rbSphereShape : public rbCollisionShape {
+	rbSphereShape(float radius) :
+		cshape(radius)
+	{}
+	
+	btSphereShape cshape;
+	btCollisionShape *get_cshape() { return &cshape; }
+};
+
+struct rbCapsuleShape : public rbCollisionShape {
+	rbCapsuleShape(float radius, float height) :
+		cshape(radius, height)
+	{}
+	
+	btCapsuleShape cshape;
+	btCollisionShape *get_cshape() { return &cshape; }
+};
+
+struct rbConeShape : public rbCollisionShape {
+	rbConeShape(float radius, float height) :
+		cshape(radius, height)
+	{}
+	
+	btConeShapeZ cshape;
+	btCollisionShape *get_cshape() { return &cshape; }
+};
+
+struct rbCylinderShape : public rbCollisionShape {
+	rbCylinderShape(float radius, float height) :
+		cshape(btVector3(radius, radius, height))
+	{}
+	
+	btCylinderShapeZ cshape;
+	btCollisionShape *get_cshape() { return &cshape; }
+};
+
+struct rbConvexHullShape : public rbCollisionShape {
+	rbConvexHullShape(float *verts, int stride, int count, float margin, bool *can_embed) {
+		btConvexHullComputer hull_computer = btConvexHullComputer();
+		
+		// try to embed the margin, if that fails don't shrink the hull
+		if (hull_computer.compute(verts, stride, count, margin, 0.0f) < 0.0f) {
+			hull_computer.compute(verts, stride, count, 0.0f, 0.0f);
+			*can_embed = false;
+		}
+		
+		cshape = btConvexHullShape(&(hull_computer.vertices[0].getX()), hull_computer.vertices.size());
+	}
+	
+	btConvexHullShape cshape;
+	btCollisionShape *get_cshape() { return &cshape; }
+};
+
+struct rbTriangleMeshShape : public rbCollisionShape {
+	rbTriangleMeshShape(rbMeshData *mesh) :
+		cshape_unscaled(mesh->index_array, true, true),
+		cshape(&cshape_unscaled, btVector3(1.0f, 1.0f, 1.0f)),
+		mesh(mesh)
+	{}
+	
+	~rbTriangleMeshShape()
+	{
+		if (mesh)
+			RB_trimesh_data_delete(mesh);
+	}
+	
+	btBvhTriangleMeshShape cshape_unscaled;
+	btScaledBvhTriangleMeshShape cshape;
+	btCollisionShape *get_cshape() { return &cshape; }
+	rbMeshData *mesh;
+};
+
+struct rbGImpactMeshShape : public rbCollisionShape {
+	rbGImpactMeshShape(rbMeshData *mesh) :
+		cshape(mesh->index_array),
+		mesh(mesh)
+	{
+		// TODO: add this to the update collision margin call?
+		cshape.updateBound();
+	}
+	
+	~rbGImpactMeshShape()
+	{
+		if (mesh)
+			RB_trimesh_data_delete(mesh);
+	}
+	
+	btGImpactMeshShape cshape;
+	btCollisionShape *get_cshape() { return &cshape; }
 	rbMeshData *mesh;
 };
 
+struct rbCompoundShape : public rbCollisionShape {
+	rbCompoundShape(bool enable_dynamic_aabb_tree) :
+		cshape(enable_dynamic_aabb_tree)
+	{}
+	
+	btCompoundShape cshape;
+	btCollisionShape *get_cshape() { return &cshape; }
+};
+
 struct rbFilterCallback : public btOverlapFilterCallback
 {
 	virtual bool needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const
@@ -349,7 +461,7 @@ rbRigidBody *RB_body_new(rbCollisionShape *shape, const float loc[3], const floa
 	btDefaultMotionState *motionState = new btDefaultMotionState(trans);
 	
 	/* make rigidbody */
-	btRigidBody::btRigidBodyConstructionInfo rbInfo(1.0f, motionState, shape->cshape);
+	btRigidBody::btRigidBodyConstructionInfo rbInfo(1.0f, motionState, shape->get_cshape());
 	
 	object->body = new btRigidBody(rbInfo);
 	
@@ -389,7 +501,7 @@ void RB_body_set_collision_shape(rbRigidBody *object, rbCollisionShape *shape)
 	btRigidBody *body = object->body;
 	
 	/* set new collision shape */
-	body->setCollisionShape(shape->cshape);
+	body->setCollisionShape(shape->get_cshape());
 	
 	/* recalculate inertia, since that depends on the collision shape... */
 	RB_body_set_mass(object, RB_body_get_mass(object));
@@ -682,7 +794,7 @@ rbGhostObject *RB_ghost_new(rbCollisionShape *shape, const float loc[3], const f
 	object->ghost = new btGhostObject();
 	object->ghost->setUserPointer(object);
 	
-	object->ghost->setCollisionShape(shape->cshape);
+	object->ghost->setCollisionShape(shape->get_cshape());
 	
 	btTransform trans;
 	trans.setOrigin(btVector3(loc[0], loc[1], loc[2]));
@@ -700,7 +812,7 @@ void RB_ghost_delete(rbGhostObject *object)
 
 void RB_ghost_set_collision_shape(rbGhostObject *body, rbCollisionShape *shape)
 {
-	body->ghost->setCollisionShape(shape->cshape);
+	body->ghost->setCollisionShape(shape->get_cshape());
 }
 
 void RB_ghost_get_transform_matrix(rbGhostObject *object, float m_out[4][4])
@@ -745,62 +857,34 @@ void RB_ghost_set_scale(rbGhostObject *object, const float scale[3])
 
 rbCollisionShape *RB_shape_new_box(float x, float y, float z)
 {
-	rbCollisionShape *shape = new rbCollisionShape;
-	shape->cshape = new btBoxShape(btVector3(x, y, z));
-	shape->mesh = NULL;
-	return shape;
+	return new rbBoxShape(x, y, z);
 }
 
 rbCollisionShape *RB_shape_new_sphere(float radius)
 {
-	rbCollisionShape *shape = new rbCollisionShape;
-	shape->cshape = new btSphereShape(radius);
-	shape->mesh = NULL;
-	return shape;
+	return new rbSphereShape(radius);
 }
 
 rbCollisionShape *RB_shape_new_capsule(float radius, float height)
 {
-	rbCollisionShape *shape = new rbCollisionShape;
-	shape->cshape = new btCapsuleShapeZ(radius, height);
-	shape->mesh = NULL;
-	return shape;
+	return new rbCapsuleShape(radius, height);
 }
 
 rbCollisionShape *RB_shape_new_cone(float radius, float height)
 {
-	rbCollisionShape *shape = new rbCollisionShape;
-	shape->cshape = new btConeShapeZ(radius, height);
-	shape->mesh = NULL;
-	return shape;
+	return new rbConeShape(radius, height);
 }
 
 rbCollisionShape *RB_shape_new_cylinder(float radius, float height)
 {
-	rbCollisionShape *shape = new rbCollisionShape;
-	shape->cshape = new btCylinderShapeZ(btVector3(radius, radius, height));
-	shape->mesh = NULL;
-	return shape;
+	return new rbCylinderShape(radius, height);
 }
 
 /* Setup (Convex Hull) ------------ */
 
 rbCollisionShape *RB_shape_new_convex_hull(float *verts, int stride, int count, float margin, bool *can_embed)
 {
-	btConvexHullComputer hull_computer = btConvexHullComputer();
-	
-	// try to embed the margin, if that fails don't shrink the hull
-	if (hull_computer.compute(verts, stride, count, margin, 0.0f) < 0.0f) {
-		hull_computer.compute(verts, stride, count, 0.0f, 0.0f);
-		*can_embed = false;
-	}
-	
-	rbCollisionShape *shape = new rbCollisionShape;
-	btConvexHullShape *hull_shape = new btConvexHullShape(&(hull_computer.vertices[0].getX()), hull_computer.vertices.size());
-	
-	shape->cshape = hull_shape;
-	shape->mesh = NULL;
-	return shape;
+	return new rbConvexHullShape(verts, stride, count, margin, can_embed);
 }
 
 /* Setup (Triangle Mesh) ---------- */
@@ -818,7 +902,7 @@ rbMeshData *RB_trimesh_data_new(int num_tris, int num_verts)
 	return mesh;
 }
 
-static void RB_trimesh_data_delete(rbMeshData *mesh)
+void RB_trimesh_data_delete(rbMeshData *mesh)
 {
 	delete mesh->index_array;
 	delete[] mesh->vertices;
@@ -847,86 +931,78 @@ void RB_trimesh_finish(rbMeshData *mesh)
 	mesh->index_array = new btTriangleIndexVertexArray(mesh->num_triangles, (int*)mesh->triangles, sizeof(rbTri),
 	                                                   mesh->num_vertices, (float*)mesh->vertices, sizeof(rbVert));
 }
- 
+
 rbCollisionShape *RB_shape_new_trimesh(rbMeshData *mesh)
 {
-	rbCollisionShape *shape = new rbCollisionShape;
-	
-	/* triangle-mesh we create is a BVH wrapper for triangle mesh data (for faster lookups) */
-	// RB_TODO perhaps we need to allow saving out this for performance when rebuilding?
-	btBvhTriangleMeshShape *unscaledShape = new btBvhTriangleMeshShape(mesh->index_array, true, true);
-	
-	shape->cshape = new btScaledBvhTriangleMeshShape(unscaledShape, btVector3(1.0f, 1.0f, 1.0f));
-	shape->mesh = mesh;
-	return shape;
+	return new rbTriangleMeshShape(mesh);
 }
 
-void RB_shape_trimesh_update(rbCollisionShape *shape, float *vertices, int num_verts, int vert_stride, float min[3], float max[3])
+rbCollisionShape *RB_shape_new_gimpact_mesh(rbMeshData *mesh)
 {
-	if (shape->mesh == NULL || num_verts != shape->mesh->num_vertices)
-		return;
+	return new rbGImpactMeshShape(mesh);
+}
+
+static bool shape_update_mesh_verts(rbMeshData *mesh, float *vertices, int num_verts, int vert_stride)
+{
+	if (mesh == NULL || num_verts != mesh->num_vertices)
+		return false;
 	
 	for (int i = 0; i < num_verts; i++) {
 		float *vert = (float*)(((char*)vertices + i * vert_stride));
-		shape->mesh->vertices[i].x = vert[0];
-		shape->mesh->vertices[i].y = vert[1];
-		shape->mesh->vertices[i].z = vert[2];
+		mesh->vertices[i].x = vert[0];
+		mesh->vertices[i].y = vert[1];
+		mesh->vertices[i].z = vert[2];
 	}
 	
-	if (shape->cshape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) {
-		btScaledBvhTriangleMeshShape *scaled_shape = (btScaledBvhTriangleMeshShape *)shape->cshape;
-		btBvhTriangleMeshShape *mesh_shape = scaled_shape->getChildShape();
-		mesh_shape->refitTree(btVector3(min[0], min[1], min[2]), btVector3(max[0], max[1], max[2]));
-	}
-	else if (shape->cshape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE) {
-		btGImpactMeshShape *mesh_shape = (btGImpactMeshShape*)shape->cshape;
-		mesh_shape->updateBound();
-	}
+	return true;
 }
 
-

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list