[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [60276] branches/soc-2013-rigid_body_sim: rigidbody: Use own structure to store mesh data for collision shapes

Sergej Reich sergej.reich at googlemail.com
Sat Sep 21 07:11:51 CEST 2013


Revision: 60276
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=60276
Author:   sergof
Date:     2013-09-21 05:11:51 +0000 (Sat, 21 Sep 2013)
Log Message:
-----------
rigidbody: Use own structure to store mesh data for collision shapes

This gives us better access to the mesh data for collision shapes.
Also should be faster to create.
TODO: look into sharing at least vertex data between collision shape and
derived mesh.

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-09-21 05:11:49 UTC (rev 60275)
+++ branches/soc-2013-rigid_body_sim/intern/rigidbody/RBI_api.h	2013-09-21 05:11:51 UTC (rev 60276)
@@ -237,7 +237,9 @@
 
 /* 1 */
 extern rbMeshData *RB_trimesh_data_new(int num_tris, int num_verts);
-extern void RB_trimesh_add_triangle(rbMeshData *mesh, const float v1[3], const float v2[3], const float v3[3]);
+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 */

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-09-21 05:11:49 UTC (rev 60275)
+++ branches/soc-2013-rigid_body_sim/intern/rigidbody/rb_bullet_api.cpp	2013-09-21 05:11:51 UTC (rev 60276)
@@ -104,10 +104,25 @@
 	int activation_type;
 };
 
+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;
 	btCollisionShape *compound;
-	btTriangleMesh *mesh;
+	rbMeshData *mesh;
 	btTriangleInfoMap *triangle_info_map;
 };
 
@@ -870,51 +885,61 @@
 
 /* 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)
 {
-	// XXX: welding threshold?
-	btTriangleMesh *mesh = new btTriangleMesh(true, false);
+	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;
 	
-	mesh->preallocateIndices(num_tris * 3);
-	mesh->preallocateVertices(num_verts);
-	
-	return (rbMeshData *) mesh;
+	return mesh;
 }
- 
-void RB_trimesh_add_triangle(rbMeshData *mesh, const float v1[3], const float v2[3], const float v3[3])
+
+static void RB_trimesh_data_delete(rbMeshData *mesh)
 {
-	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);
+	delete mesh->index_array;
+	delete mesh->vertices;
+	delete mesh->triangles;
+	delete mesh;
 }
+
+void RB_trimesh_add_vertices(rbMeshData *mesh, float *vertices, int num_verts, int vert_stride)
+{
+	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->triangle_info_map = new btTriangleInfoMap();
 //	btGenerateInternalEdgeInfo(unscaledShape, shape->triangle_info_map);
 	
 	shape->cshape = new btScaledBvhTriangleMeshShape(unscaledShape, btVector3(1.0f, 1.0f, 1.0f));
-	shape->mesh = tmesh;
+	shape->mesh = mesh;
 	
 	shape->compound = new btCompoundShape();
 	btTransform compound_transform;
@@ -927,14 +952,12 @@
 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;
 	shape->triangle_info_map = NULL;
 	
 	shape->compound = new btCompoundShape();
@@ -1034,7 +1057,7 @@
 			delete child_shape;
 	}
 	if (shape->mesh)
-		delete shape->mesh;
+		RB_trimesh_data_delete(shape->mesh);
 	if (shape->triangle_info_map)
 		delete shape->triangle_info_map;
 	if (shape->cshape != shape->compound)

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-09-21 05:11:49 UTC (rev 60275)
+++ branches/soc-2013-rigid_body_sim/source/blender/blenkernel/intern/rigidbody.c	2013-09-21 05:11:51 UTC (rev 60276)
@@ -287,6 +287,7 @@
 		int totvert;
 		int totface;
 		int tottris = 0;
+		int triangle_index = 0;
 
 		if (ob->rigidbody_object->mesh_source == RBO_MESH_DEFORM) {
 			dm = ob->derivedDeform;
@@ -323,28 +324,22 @@
 			/* init mesh data for collision shape */
 			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