diff options
author | Sergej Reich <sergej.reich@googlemail.com> | 2013-12-26 20:49:08 +0400 |
---|---|---|
committer | Sergej Reich <sergej.reich@googlemail.com> | 2013-12-26 21:38:06 +0400 |
commit | c96601138dfe08705fd4375527d322176b8fa126 (patch) | |
tree | e9f73027e591774e5a1a90c50730bac966d14df1 /intern/rigidbody | |
parent | 2260a7dbc0b6150489832dd94160512d1760fb00 (diff) |
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.
Diffstat (limited to 'intern/rigidbody')
-rw-r--r-- | intern/rigidbody/RBI_api.h | 6 | ||||
-rw-r--r-- | intern/rigidbody/rb_bullet_api.cpp | 85 |
2 files changed, 61 insertions, 30 deletions
diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h index 7a04961f99d..97e8e6891ff 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 ecb07c628d2..31f7f386663 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; } |