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
                         *

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to