[Bf-blender-cvs] [c966011] master: Rigidbody: Use own structure to store mesh data for collision shapes

Sergej Reich noreply at git.blender.org
Thu Dec 26 18:39:48 CET 2013


Commit: c96601138dfe08705fd4375527d322176b8fa126
Author: Sergej Reich
Date:   Thu Dec 26 17:49:08 2013 +0100
https://developer.blender.org/rBc96601138dfe08705fd4375527d322176b8fa126

Rigidbody: Use own structure to store mesh data for collision shapes

This gives us better access to the data and should also be faster to
create.

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

M	intern/rigidbody/RBI_api.h
M	intern/rigidbody/rb_bullet_api.cpp
M	source/blender/blenkernel/intern/rigidbody.c

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

diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h
index 7a04961..97e8e68 100644
--- a/intern/rigidbody/RBI_api.h
+++ b/intern/rigidbody/RBI_api.h
@@ -227,8 +227,10 @@ extern rbCollisionShape *RB_shape_new_convex_hull(float *verts, int stride, int
 /* Setup (Triangle Mesh) ---------- */
 
 /* 1 */
-extern rbMeshData *RB_trimesh_data_new(void);
-extern void RB_trimesh_add_triangle(rbMeshData *mesh, const float v1[3], const float v2[3], const float v3[3]);
+extern rbMeshData *RB_trimesh_data_new(int num_tris, int num_verts);
+extern void RB_trimesh_add_vertices(rbMeshData *mesh, float *vertices, int num_verts, int vert_stride);
+extern void RB_trimesh_add_triangle_indices(rbMeshData *mesh, int num, int index0, int index1, int index2);
+extern void RB_trimesh_finish(rbMeshData *mesh);
 /* 2a - Triangle Meshes */
 extern rbCollisionShape *RB_shape_new_trimesh(rbMeshData *mesh);
 /* 2b - GImpact Meshes */
diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp
index ecb07c6..31f7f38 100644
--- a/intern/rigidbody/rb_bullet_api.cpp
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -86,9 +86,24 @@ struct rbRigidBody {
 	int col_groups;
 };
 
+struct rbVert {
+	float x, y, z;
+};
+struct rbTri {
+	int v0, v1, v2;
+};
+
+struct rbMeshData {
+	btTriangleIndexVertexArray *index_array;
+	rbVert *vertices;
+	rbTri *triangles;
+	int num_vertices;
+	int num_triangles;
+};
+
 struct rbCollisionShape {
 	btCollisionShape *cshape;
-	btTriangleMesh *mesh;
+	rbMeshData *mesh;
 };
 
 struct rbFilterCallback : public btOverlapFilterCallback
@@ -692,57 +707,71 @@ rbCollisionShape *RB_shape_new_convex_hull(float *verts, int stride, int count,
 
 /* Setup (Triangle Mesh) ---------- */
 
-/* Need to call rbTriMeshNewData() followed by rbTriMeshAddTriangle() several times 
- * to set up the mesh buffer BEFORE calling rbShapeNewTriMesh(). Otherwise,
- * we get nasty crashes...
- */
+/* Need to call RB_trimesh_finish() after creating triangle mesh and adding vertices and triangles */
+
+rbMeshData *RB_trimesh_data_new(int num_tris, int num_verts)
+{
+	rbMeshData *mesh = new rbMeshData;
+	mesh->vertices = new rbVert[num_verts];
+	mesh->triangles = new rbTri[num_tris];
+	mesh->num_vertices = num_verts;
+	mesh->num_triangles = num_tris;
+	
+	return mesh;
+}
 
-rbMeshData *RB_trimesh_data_new()
+static void RB_trimesh_data_delete(rbMeshData *mesh)
 {
-	// XXX: welding threshold?
-	return (rbMeshData *) new btTriangleMesh(true, false);
+	delete mesh->index_array;
+	delete mesh->vertices;
+	delete mesh->triangles;
+	delete mesh;
 }
  
-void RB_trimesh_add_triangle(rbMeshData *mesh, const float v1[3], const float v2[3], const float v3[3])
+void RB_trimesh_add_vertices(rbMeshData *mesh, float *vertices, int num_verts, int vert_stride)
 {
-	btTriangleMesh *meshData = reinterpret_cast<btTriangleMesh*>(mesh);
-	
-	/* cast vertices to usable forms for Bt-API */
-	btVector3 vtx1((btScalar)v1[0], (btScalar)v1[1], (btScalar)v1[2]);
-	btVector3 vtx2((btScalar)v2[0], (btScalar)v2[1], (btScalar)v2[2]);
-	btVector3 vtx3((btScalar)v3[0], (btScalar)v3[1], (btScalar)v3[2]);
-	
-	/* add to the mesh 
-	 *	- remove duplicated verts is enabled
-	 */
-	meshData->addTriangle(vtx1, vtx2, vtx3, false);
+	for (int i = 0; i < num_verts; i++) {
+		float *vert = (float*)(((char*)vertices + i * vert_stride));
+		mesh->vertices[i].x = vert[0];
+		mesh->vertices[i].y = vert[1];
+		mesh->vertices[i].z = vert[2];
+	}
+}
+void RB_trimesh_add_triangle_indices(rbMeshData *mesh, int num, int index0, int index1, int index2)
+{
+	mesh->triangles[num].v0 = index0;
+	mesh->triangles[num].v1 = index1;
+	mesh->triangles[num].v2 = index2;
+}
+
+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;
-	btTriangleMesh *tmesh = reinterpret_cast<btTriangleMesh*>(mesh);
 	
 	/* 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(tmesh, true, true);
+	btBvhTriangleMeshShape *unscaledShape = new btBvhTriangleMeshShape(mesh->index_array, true, true);
 	
 	shape->cshape = new btScaledBvhTriangleMeshShape(unscaledShape, btVector3(1.0f, 1.0f, 1.0f));
-	shape->mesh = tmesh;
+	shape->mesh = mesh;
 	return shape;
 }
 
 rbCollisionShape *RB_shape_new_gimpact_mesh(rbMeshData *mesh)
 {
 	rbCollisionShape *shape = new rbCollisionShape;
-	/* interpret mesh buffer as btTriangleIndexVertexArray (i.e. an impl of btStridingMeshInterface) */
-	btTriangleMesh *tmesh = reinterpret_cast<btTriangleMesh*>(mesh);
 	
-	btGImpactMeshShape *gimpactShape = new btGImpactMeshShape(tmesh);
+	btGImpactMeshShape *gimpactShape = new btGImpactMeshShape(mesh->index_array);
 	gimpactShape->updateBound(); // TODO: add this to the update collision margin call?
 	
 	shape->cshape = gimpactShape;
-	shape->mesh = tmesh;
+	shape->mesh = mesh;
 	return shape;
 }
 
@@ -756,7 +785,7 @@ void RB_shape_delete(rbCollisionShape *shape)
 			delete child_shape;
 	}
 	if (shape->mesh)
-		delete shape->mesh;
+		RB_trimesh_data_delete(shape->mesh);
 	delete shape->cshape;
 	delete shape;
 }
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index fa455fa..22126b7 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -282,6 +282,8 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
 		MFace *mface;
 		int totvert;
 		int totface;
+		int tottris = 0;
+		int triangle_index = 0;
 
 		dm = rigidbody_get_mesh(ob);
 
@@ -303,32 +305,32 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
 		else {
 			rbMeshData *mdata;
 			int i;
+			
+			/* count triangles */
+			for (i = 0; i < totface; i++) {
+				(mface[i].v4) ? (tottris += 2) : (tottris += 1);
+			}
 
 			/* init mesh data for collision shape */
-			mdata = RB_trimesh_data_new();
+			mdata = RB_trimesh_data_new(tottris, totvert);
+			
+			RB_trimesh_add_vertices(mdata, (float*)mvert, totvert, sizeof(MVert));
 
 			/* loop over all faces, adding them as triangles to the collision shape
 			 * (so for some faces, more than triangle will get added)
 			 */
 			for (i = 0; (i < totface) && (mface) && (mvert); i++, mface++) {
 				/* add first triangle - verts 1,2,3 */
-				{
-					MVert *va = (mface->v1 < totvert) ? (mvert + mface->v1) : (mvert);
-					MVert *vb = (mface->v2 < totvert) ? (mvert + mface->v2) : (mvert);
-					MVert *vc = (mface->v3 < totvert) ? (mvert + mface->v3) : (mvert);
-
-					RB_trimesh_add_triangle(mdata, va->co, vb->co, vc->co);
-				}
+				RB_trimesh_add_triangle_indices(mdata, triangle_index, mface->v1, mface->v2, mface->v3);
+				triangle_index++;
 
 				/* add second triangle if needed - verts 1,3,4 */
 				if (mface->v4) {
-					MVert *va = (mface->v1 < totvert) ? (mvert + mface->v1) : (mvert);
-					MVert *vb = (mface->v3 < totvert) ? (mvert + mface->v3) : (mvert);
-					MVert *vc = (mface->v4 < totvert) ? (mvert + mface->v4) : (mvert);
-
-					RB_trimesh_add_triangle(mdata, va->co, vb->co, vc->co);
+					RB_trimesh_add_triangle_indices(mdata, triangle_index, mface->v1, mface->v3, mface->v4);
+					triangle_index++;
 				}
 			}
+			RB_trimesh_finish(mdata);
 
 			/* construct collision shape
 			 *




More information about the Bf-blender-cvs mailing list