Speedup for bullet creating convex hull meshes
authorCampbell Barton <ideasman42@gmail.com>
Sun, 22 Mar 2009 21:04:28 +0000 (21:04 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sun, 22 Mar 2009 21:04:28 +0000 (21:04 +0000)
In a simple test with ~12000 verts, overall BGE startup time went from ~4.5 sec to a bit under a second.

- before adding each vert it did a check for a duplicates.
- Using RAS_Polygon verts can give a lot of duplicates because the verts also store UV's and normals.
- Was increasing the array one item at a time, now resize the array once.
- Use the blender mesh mvert array rather then RAS_TexVert's, so needed to include some DNA headers.

source/gameengine/Physics/Bullet/CMakeLists.txt
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
source/gameengine/Physics/Bullet/Makefile
source/gameengine/Physics/Bullet/SConscript

index 6c733786caf0af3a49aa2cf16268ac185070d2d0..83b77db4efda051fe182840d5c42e0a128b741ab 100644 (file)
@@ -34,6 +34,7 @@ SET(INC
   ../../../kernel/gen_system
   ../../../../intern/string
   ../../Rasterizer
+  ../../../../source/blender/makesdna
 )
 
 BLENDERLIB(bf_bullet "${SRC}" "${INC}")
index eecdea55349b4923674b1775b796acd99d511a56..61d02847164ca2b97e661fa584110bb1201667d2 100644 (file)
@@ -24,10 +24,14 @@ subject to the following restrictions:
 #include "BulletSoftBody/btSoftBodyHelpers.h"
 #include "LinearMath/btConvexHull.h"
 #include "BulletCollision/Gimpact/btGImpactShape.h"
+#include "BulletCollision/Gimpact/btGImpactShape.h"
 
 
 #include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
 
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
 class BP_Proxy;
 
 ///todo: fill all the empty CcdPhysicsController methods, hook them up to the btRigidBody class
@@ -1315,37 +1319,64 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo
 
        numvalidpolys = 0;
 
-       for (int p2=0; p2<numpolys; p2++)
+       if (polytope)
        {
-               RAS_Polygon* poly = meshobj->GetPolygon(p2);
-
-               // only add polygons that have the collisionflag set
-               if (poly->IsCollider())
-               {   
-                       //Bullet can raycast any shape, so
-                       if (polytope)
+               Mesh *blen_mesh= meshobj->GetMesh();
+               vector<bool> vuser_array(blen_mesh->totvert, false);
+               
+               unsigned int tot_bt_verts= 0;
+               unsigned int orig_index;
+               int i;
+               
+               // Tag verts we're using
+               for (int p2=0; p2<numpolys; p2++)
+               {
+                       RAS_Polygon* poly= meshobj->GetPolygon(p2);
+                       
+                       // only add polygons that have the collisionflag set
+                       if (poly->IsCollider())
                        {
-                               for (int i=0;i<poly->VertexCount();i++)
+                               for (i=0;i<poly->VertexCount();i++)
                                {
-                                       const float* vtx = poly->GetVertex(i)->getXYZ();
-                                       btVector3       point(vtx[0],vtx[1],vtx[2]);
-                                       //avoid duplicates (could better directly use vertex offsets, rather than a vertex compare)
-                                       bool found = false;
-                                       for (int j=0;j<m_vertexArray.size();j++)
+                                       orig_index= poly->GetVertex(i)->getOrigIndex();
+                                       
+                                       if (vuser_array[orig_index]==false)
                                        {
-                                               if (m_vertexArray[j]==point)
-                                               {
-                                                       found = true;
-                                                       break;
-                                               }
+                                               vuser_array[orig_index]= true;
+                                               tot_bt_verts++;
                                        }
-                                       if (!found)
-                                               m_vertexArray.push_back(point);
-
-                                       numvalidpolys++;
                                }
-                       } else
+                       }
+               }
+               
+               m_vertexArray.resize(tot_bt_verts);
+               
+               // Copy used verts directly from the meshes vert location to the bullet vector array
+               MVert *mv= blen_mesh->mvert;
+               btVector3 *bt= &m_vertexArray[0];
+               
+               for (i=0;i<vuser_array.size();i++, mv++)
+               {
+                       if (vuser_array[i]==true)
                        {
+                               bt->setX( mv->co[0] );
+                               bt->setY( mv->co[1] );
+                               bt->setZ( mv->co[2] );
+                               bt++;
+                       }
+               }
+               numvalidpolys++;
+       }
+       else {
+               for (int p2=0; p2<numpolys; p2++)
+               {
+                       RAS_Polygon* poly = meshobj->GetPolygon(p2);
+
+                       // only add polygons that have the collisionflag set
+                       if (poly->IsCollider())
+                       {   
+                               //Bullet can raycast any shape, so
+                       
                                {
                                        const float* vtx = poly->GetVertex(2)->getXYZ();
                                        btVector3 vertex0(vtx[0],vtx[1],vtx[2]);
@@ -1379,7 +1410,7 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo
                                        m_polygonIndexArray.push_back(p2);
                                        numvalidpolys++;
                                }
-                       }               
+                       }
                }
        }
 
index d5570e7583391fed6d4b7fc884bc6553373f3c09..bf3573138f74f837dfdcc9265d69086d78f2b5fc 100644 (file)
@@ -43,4 +43,5 @@ CPPFLAGS += -I../../../kernel/gen_system
 CPPFLAGS += -I../../Physics/common
 CPPFLAGS += -I../../Physics/Dummy
 CPPFLAGS += -I../../Rasterizer
+CPPFLAGS += -I../../../../source/blender/makesdna
 
index 0d5bf4933d89339448198564935b60a41cc9547f..868a4d66af0b137698679c9aca14691adb28b128 100644 (file)
@@ -3,7 +3,7 @@ Import ('env')
 
 sources = 'CcdPhysicsEnvironment.cpp CcdPhysicsController.cpp'
 
-incs = '. ../common #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/Rasterizer'
+incs = '. ../common #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/Rasterizer #source/blender/makesdna'
 
 incs += ' ' + env['BF_BULLET_INC']