diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e3321091..2f04917ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -192,6 +192,10 @@ ENDIF() OPTION(BUILD_BULLET3 "Set when you want to build Bullet 3" ON) OPTION(BUILD_PYBULLET "Set when you want to build pybullet (experimental Python bindings for Bullet)" OFF) +IF(BUILD_PYBULLET) + FIND_PACKAGE(PythonLibs 2.7 REQUIRED) + SET(BUILD_SHARED_LIBS ON CACHE BOOL "Shared Libs" FORCE) +ENDIF(BUILD_PYBULLET) IF(BUILD_BULLET3) IF(APPLE) diff --git a/examples/ExampleBrowser/ExampleEntries.cpp b/examples/ExampleBrowser/ExampleEntries.cpp index 3ec1403d6..08f71cf69 100644 --- a/examples/ExampleBrowser/ExampleEntries.cpp +++ b/examples/ExampleBrowser/ExampleEntries.cpp @@ -83,8 +83,10 @@ static ExampleEntry gDefaultExamples[]= ExampleEntry(0,"API"), + ExampleEntry(1,"Basic Example","Create some rigid bodies using box collision shapes. This is a good example to familiarize with the basic initialization of Bullet. The Basic Example can also be compiled without graphical user interface, as a console application. Press W for wireframe, A to show AABBs, I to suspend/restart physics simulation. Press D to toggle auto-deactivation of the simulation. ", BasicExampleCreateFunc), + ExampleEntry(1,"Rolling Friction", "Damping is often not good enough to keep rounded objects from rolling down a sloped surface. Instead, you can set the rolling friction of a rigid body. Generally it is best to leave the rolling friction to zero, to avoid artifacts.", RollingFrictionCreateFunc), ExampleEntry(1,"Constraints","Show the use of the various constraints in Bullet. Press the L key to visualize the constraint limits. Press the C key to visualize the constraint frames.", diff --git a/examples/HelloWorld/HelloWorld.cpp b/examples/HelloWorld/HelloWorld.cpp index f7a195746..e51e6d541 100644 --- a/examples/HelloWorld/HelloWorld.cpp +++ b/examples/HelloWorld/HelloWorld.cpp @@ -44,20 +44,24 @@ int main(int argc, char** argv) ///-----initialization_end----- - ///create a few basic rigid bodies - btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); - //keep track of the shapes, we release memory at exit. //make sure to re-use collision shapes among rigid bodies whenever possible! btAlignedObjectArray collisionShapes; - collisionShapes.push_back(groundShape); - btTransform groundTransform; - groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0,-56,0)); + ///create a few basic rigid bodies + //the ground is a cube of side 100 at position y = -56. + //the sphere will hit it at y = -6, with center at -5 { + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); + + collisionShapes.push_back(groundShape); + + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,-56,0)); + btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static @@ -113,7 +117,7 @@ int main(int argc, char** argv) ///-----stepsimulation_start----- - for (i=0;i<100;i++) + for (i=0;i<150;i++) { dynamicsWorld->stepSimulation(1.f/60.f,10); @@ -178,9 +182,5 @@ int main(int argc, char** argv) //next line is optional: it will be cleared by the destructor when the array goes out of scope collisionShapes.clear(); - - ///-----cleanup_end----- - printf("Press a key to exit\n"); - getchar(); } diff --git a/examples/OpenGLWindow/X11OpenGLWindow.cpp b/examples/OpenGLWindow/X11OpenGLWindow.cpp index e6d0f666d..f2a077145 100644 --- a/examples/OpenGLWindow/X11OpenGLWindow.cpp +++ b/examples/OpenGLWindow/X11OpenGLWindow.cpp @@ -1076,6 +1076,20 @@ b3KeyboardCallback X11OpenGLWindow::getKeyboardCallback() return m_data->m_keyboardCallback; } +int X11OpenGLWindow::getWidth() const +{ + if (m_data) + return m_data->m_glWidth; + return 0; +} +int X11OpenGLWindow::getHeight() const +{ + if (m_data) + return m_data->m_glHeight; + return 0; +} + + #include int X11OpenGLWindow::fileOpenDialog(char* filename, int maxNameLength) diff --git a/examples/OpenGLWindow/X11OpenGLWindow.h b/examples/OpenGLWindow/X11OpenGLWindow.h index cc28aae1a..fd88689bc 100644 --- a/examples/OpenGLWindow/X11OpenGLWindow.h +++ b/examples/OpenGLWindow/X11OpenGLWindow.h @@ -54,7 +54,7 @@ public: virtual void setResizeCallback(b3ResizeCallback resizeCallback); virtual void setWheelCallback(b3WheelCallback wheelCallback); virtual void setKeyboardCallback( b3KeyboardCallback keyboardCallback); - + virtual b3MouseMoveCallback getMouseMoveCallback(); virtual b3MouseButtonCallback getMouseButtonCallback(); virtual b3ResizeCallback getResizeCallback(); @@ -65,9 +65,14 @@ public: virtual void setWindowTitle(const char* title); + virtual int getWidth() const; + + virtual int getHeight() const; + int fileOpenDialog(char* filename, int maxNameLength); }; + #endif diff --git a/examples/pybullet/CMakeLists.txt b/examples/pybullet/CMakeLists.txt index b5ee53a0e..a583192ab 100644 --- a/examples/pybullet/CMakeLists.txt +++ b/examples/pybullet/CMakeLists.txt @@ -4,7 +4,7 @@ INCLUDE_DIRECTORIES( ${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/examples ${BULLET_PHYSICS_SOURCE_DIR}/examples/ThirdPartyLibs - /usr/include/python2.7 + ${PYTHON_INCLUDE_DIRS} ) SET(pybullet_SRCS @@ -18,7 +18,7 @@ ADD_LIBRARY(pybullet ${pybullet_SRCS}) SET_TARGET_PROPERTIES(pybullet PROPERTIES VERSION ${BULLET_VERSION}) SET_TARGET_PROPERTIES(pybullet PROPERTIES SOVERSION ${BULLET_VERSION}) - TARGET_LINK_LIBRARIES(pybullet BulletExampleBrowserLib BulletSoftBody BulletDynamics BulletCollision BulletInverseDynamicsUtils BulletInverseDynamics LinearMath OpenGLWindow gwen Bullet3Common Python) + TARGET_LINK_LIBRARIES(pybullet BulletExampleBrowserLib BulletSoftBody BulletDynamics BulletCollision BulletInverseDynamicsUtils BulletInverseDynamics LinearMath OpenGLWindow gwen Bullet3Common ${PYTHON_LIBRARIES}) ENDIF (BUILD_SHARED_LIBS) diff --git a/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp b/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp index c505ed5d5..fa4cac660 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp +++ b/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp @@ -790,23 +790,50 @@ void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape, } } } else { - ///@todo : use AABB tree or other BVH acceleration structure! if (collisionShape->isCompound()) { - BT_PROFILE("convexSweepCompound"); - const btCompoundShape* compoundShape = static_cast(collisionShape); - int i=0; - for (i=0;igetNumChildShapes();i++) + struct btCompoundLeafCallback : btDbvt::ICollide { - btTransform childTrans = compoundShape->getChildTransform(i); - const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i); - btTransform childWorldTrans = colObjWorldTransform * childTrans; - - struct LocalInfoAdder : public ConvexResultCallback { - ConvexResultCallback* m_userCallback; + btCompoundLeafCallback( + const btCollisionObjectWrapper* colObjWrap, + const btConvexShape* castShape, + const btTransform& convexFromTrans, + const btTransform& convexToTrans, + btScalar allowedPenetration, + const btCompoundShape* compoundShape, + const btTransform& colObjWorldTransform, + ConvexResultCallback& resultCallback) + : + m_colObjWrap(colObjWrap), + m_castShape(castShape), + m_convexFromTrans(convexFromTrans), + m_convexToTrans(convexToTrans), + m_allowedPenetration(allowedPenetration), + m_compoundShape(compoundShape), + m_colObjWorldTransform(colObjWorldTransform), + m_resultCallback(resultCallback) { + } + + const btCollisionObjectWrapper* m_colObjWrap; + const btConvexShape* m_castShape; + const btTransform& m_convexFromTrans; + const btTransform& m_convexToTrans; + btScalar m_allowedPenetration; + const btCompoundShape* m_compoundShape; + const btTransform& m_colObjWorldTransform; + ConvexResultCallback& m_resultCallback; + + public: + + void ProcessChild(int index, const btTransform& childTrans, const btCollisionShape* childCollisionShape) + { + btTransform childWorldTrans = m_colObjWorldTransform * childTrans; + + struct LocalInfoAdder : public ConvexResultCallback { + ConvexResultCallback* m_userCallback; int m_i; - LocalInfoAdder (int i, ConvexResultCallback *user) + LocalInfoAdder(int i, ConvexResultCallback *user) : m_userCallback(user), m_i(i) { m_closestHitFraction = m_userCallback->m_closestHitFraction; @@ -815,27 +842,66 @@ void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape, { return m_userCallback->needsCollision(p); } - virtual btScalar addSingleResult (btCollisionWorld::LocalConvexResult& r, bool b) - { - btCollisionWorld::LocalShapeInfo shapeInfo; - shapeInfo.m_shapePart = -1; - shapeInfo.m_triangleIndex = m_i; - if (r.m_localShapeInfo == NULL) - r.m_localShapeInfo = &shapeInfo; - const btScalar result = m_userCallback->addSingleResult(r, b); - m_closestHitFraction = m_userCallback->m_closestHitFraction; - return result; - - } - }; + virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& r, bool b) + { + btCollisionWorld::LocalShapeInfo shapeInfo; + shapeInfo.m_shapePart = -1; + shapeInfo.m_triangleIndex = m_i; + if (r.m_localShapeInfo == NULL) + r.m_localShapeInfo = &shapeInfo; + const btScalar result = m_userCallback->addSingleResult(r, b); + m_closestHitFraction = m_userCallback->m_closestHitFraction; + return result; - LocalInfoAdder my_cb(i, &resultCallback); - - btCollisionObjectWrapper tmpObj(colObjWrap,childCollisionShape,colObjWrap->getCollisionObject(),childWorldTrans,-1,i); + } + }; - objectQuerySingleInternal(castShape, convexFromTrans,convexToTrans, - &tmpObj,my_cb, allowedPenetration); - + LocalInfoAdder my_cb(index, &m_resultCallback); + + btCollisionObjectWrapper tmpObj(m_colObjWrap, childCollisionShape, m_colObjWrap->getCollisionObject(), childWorldTrans, -1, index); + + objectQuerySingleInternal(m_castShape, m_convexFromTrans, m_convexToTrans, &tmpObj, my_cb, m_allowedPenetration); + } + + void Process(const btDbvtNode* leaf) + { + // Processing leaf node + int index = leaf->dataAsInt; + + btTransform childTrans = m_compoundShape->getChildTransform(index); + const btCollisionShape* childCollisionShape = m_compoundShape->getChildShape(index); + + ProcessChild(index, childTrans, childCollisionShape); + } + }; + + BT_PROFILE("convexSweepCompound"); + const btCompoundShape* compoundShape = static_cast(collisionShape); + + btVector3 fromLocalAabbMin, fromLocalAabbMax; + btVector3 toLocalAabbMin, toLocalAabbMax; + + castShape->getAabb(colObjWorldTransform.inverse() * convexFromTrans, fromLocalAabbMin, fromLocalAabbMax); + castShape->getAabb(colObjWorldTransform.inverse() * convexToTrans, toLocalAabbMin, toLocalAabbMax); + + fromLocalAabbMin.setMin(toLocalAabbMin); + fromLocalAabbMax.setMax(toLocalAabbMax); + + btCompoundLeafCallback callback(colObjWrap, castShape, convexFromTrans, convexToTrans, + allowedPenetration, compoundShape, colObjWorldTransform, resultCallback); + + const btDbvt* tree = compoundShape->getDynamicAabbTree(); + if (tree) { + const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds = btDbvtVolume::FromMM(fromLocalAabbMin, fromLocalAabbMax); + tree->collideTV(tree->m_root, bounds, callback); + } else { + int i; + for (i=0;igetNumChildShapes();i++) + { + const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i); + btTransform childTrans = compoundShape->getChildTransform(i); + callback.ProcessChild(i, childTrans, childCollisionShape); + } } } } diff --git a/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp b/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp index 0623e351a..c1aa6ca46 100644 --- a/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp +++ b/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp @@ -22,6 +22,8 @@ subject to the following restrictions: #include "LinearMath/btQuaternion.h" #include "LinearMath/btSerializer.h" +#include "btConvexPolyhedron.h" +#include "LinearMath/btConvexHullComputer.h" btConvexHullShape ::btConvexHullShape (const btScalar* points,int numPoints,int stride) : btPolyhedralConvexAabbCachingShape () { @@ -121,10 +123,17 @@ btVector3 btConvexHullShape::localGetSupportingVertex(const btVector3& vec)const } - - - - +void btConvexHullShape::optimizeConvexHull() +{ + btConvexHullComputer conv; + conv.compute(&m_unscaledPoints[0].getX(), sizeof(btVector3),m_unscaledPoints.size(),0.f,0.f); + int numVerts = conv.vertices.size(); + m_unscaledPoints.resize(0); + for (int i=0;i