diff --git a/ChangeLog.txt b/ChangeLog.txt index a7572de55..6f482c9a8 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,6 +1,15 @@ Bullet Continuous Collision Detection and Physics Library Erwin Coumans +2007 May 20 + - btAxisSweep3: Fixed a bug in btAxisSweep3 (sweep and prune) related to object removal. Only showed up when at least one btStaticPlaneShape was inserted. + Thanks tbp for more details on reproducing case. + - btAxisSweep3: Fixed issue with full 32bit precision btAxisSweep3 (define BP_USE_FIXEDPOINT_INT_32), it used only 0xffff/65536 for quantization instead of full integer space (0xffffffff) + - btRaycastVehicle: Added 'getForwardVector' and getCurrentSpeedKmHour utility functions + - Fixed local scaling issues (btConvexTriangleMeshShape, btBvhTriangleMeshShape, removed scaling from btMatrix3x3). + Thanks Volker for reporting! + - Added second filename search, so that starting BspDemo and ConvexDecompositionDemo from within Visual Studio (without setting the starting path) still works + 2007 April 22 - Added braking functionality to btRaycastVehicle - Removed tons of warnings, under MSVC 2005 compilation in -W4 diff --git a/Demos/BspDemo/BspDemo.cpp b/Demos/BspDemo/BspDemo.cpp index 17f3f8393..889b54de1 100644 --- a/Demos/BspDemo/BspDemo.cpp +++ b/Demos/BspDemo/BspDemo.cpp @@ -161,6 +161,15 @@ void BspDemo::initPhysics(char* bspfilename) bspfilename = "../../BspDemo.bsp"; file = fopen(bspfilename,"r"); } + if (!file) + { + //try again other path, + //sight... visual studio leaves the current working directory in the projectfiles folder + //instead of executable folder. who wants this default behaviour?!? + bspfilename = "BspDemo.bsp"; + file = fopen(bspfilename,"r"); + } + if (file) { BspLoader bspLoader; diff --git a/Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.cpp b/Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.cpp index 03d94d150..f9339c0c3 100644 --- a/Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.cpp +++ b/Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.cpp @@ -78,6 +78,11 @@ void ConvexDecompositionDemo::initPhysics(const char* filename) tcount = wo.loadObj(filename); + if (!tcount) + { + //when running this app from visual studio, the default starting folder is different, so make a second attempt... + tcount = wo.loadObj("../../file.obj"); + } btCollisionDispatcher* dispatcher = new btCollisionDispatcher(); diff --git a/VERSION b/VERSION index b44a85c94..5235f81f7 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ -Bullet Collision Detection and Physics Library version 2.50b +Bullet Collision Detection and Physics Library version 2.51 http://bullet.sourceforge.net diff --git a/configure.ac b/configure.ac index 0d2aab6ff..2c7124fcd 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ AC_PREREQ([2.54]) #---------------------------------------------------------------------------- AC_INIT( [bullet], - [2.50], + [2.51], [bullet@erwincoumans.com]) CS_PACKAGEINFO( [Bullet Continuous Collision Detection and Physics Library], diff --git a/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp b/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp index 6a9a8c1b1..3252ddb87 100644 --- a/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp +++ b/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp @@ -21,6 +21,30 @@ #include +#ifdef DEBUG_BROADPHASE +#include +void btAxisSweep3::debugPrintAxis(int axis, bool checkCardinality) +{ + int numEdges = m_pHandles[0].m_maxEdges[axis]; + printf("SAP Axis %d, numEdges=%d\n",axis,numEdges); + + int i; + for (i=0;im_handle); + int handleIndex = pEdge->IsMax()? pHandlePrev->m_maxEdges[axis] : pHandlePrev->m_minEdges[axis]; + char beginOrEnd; + beginOrEnd=pEdge->IsMax()?'E':'B'; + printf(" [%c,h=%d,p=%x,i=%d]\n",beginOrEnd,pEdge->m_handle,pEdge->m_pos,handleIndex); + } + + if (checkCardinality) + assert(numEdges == m_numHandles*2+1); +} +#endif //DEBUG_BROADPHASE + + btBroadphaseProxy* btAxisSweep3::createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask) { (void)shapeType; @@ -41,6 +65,7 @@ void btAxisSweep3::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,con { Handle* handle = static_cast(proxy); updateHandle(handle->m_handleId,aabbMin,aabbMax); + } @@ -55,7 +80,7 @@ btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAab //assert(bounds.HasVolume()); // 1 handle is reserved as sentinel - assert(maxHandles > 1 && maxHandles < BP_MAX_HANDLES); + btAssert(maxHandles > 1 && maxHandles < BP_MAX_HANDLES); // init bounds m_worldAabbMin = worldAabbMin; @@ -63,7 +88,9 @@ btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAab btVector3 aabbSize = m_worldAabbMax - m_worldAabbMin; - m_quantize = btVector3(btScalar(65535.0),btScalar(65535.0),btScalar(65535.0)) / aabbSize; + BP_FP_INT_TYPE maxInt = BP_HANDLE_SENTINEL; + + m_quantize = btVector3(btScalar(maxInt),btScalar(maxInt),btScalar(maxInt)) / aabbSize; // allocate handles buffer and put all handles on free list m_pHandles = new Handle[maxHandles]; @@ -98,7 +125,12 @@ btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAab m_pEdges[axis][0].m_handle = 0; m_pEdges[axis][1].m_pos = BP_HANDLE_SENTINEL; m_pEdges[axis][1].m_handle = 0; +#ifdef DEBUG_BROADPHASE + debugPrintAxis(axis); +#endif //DEBUG_BROADPHASE + } + } btAxisSweep3::~btAxisSweep3() @@ -172,9 +204,11 @@ BP_FP_INT_TYPE btAxisSweep3::addHandle(const btPoint3& aabbMin,const btPoint3& a // compute current limit of edge arrays BP_FP_INT_TYPE limit = m_numHandles * 2; + // insert new edges just inside the max boundary edge for (BP_FP_INT_TYPE axis = 0; axis < 3; axis++) { + m_pHandles[0].m_maxEdges[axis] += 2; m_pEdges[axis][limit + 1] = m_pEdges[axis][limit - 1]; @@ -197,7 +231,6 @@ BP_FP_INT_TYPE btAxisSweep3::addHandle(const btPoint3& aabbMin,const btPoint3& a sortMinDown(2, pHandle->m_minEdges[2], true); sortMaxDown(2, pHandle->m_maxEdges[2], true); - //PrintAxis(1); return handle; } @@ -205,6 +238,7 @@ BP_FP_INT_TYPE btAxisSweep3::addHandle(const btPoint3& aabbMin,const btPoint3& a void btAxisSweep3::removeHandle(BP_FP_INT_TYPE handle) { + Handle* pHandle = getHandle(handle); //explicitly remove the pairs containing the proxy @@ -215,15 +249,19 @@ void btAxisSweep3::removeHandle(BP_FP_INT_TYPE handle) // compute current limit of edge arrays int limit = m_numHandles * 2; + int axis; for (axis = 0;axis<3;axis++) { Edge* pEdges = m_pEdges[axis]; + m_pHandles[0].m_maxEdges[axis] -= 2; int maxEdge= pHandle->m_maxEdges[axis]; - pEdges[maxEdge].m_pos = BP_HANDLE_SENTINEL; + //pEdges[maxEdge].m_pos = BP_HANDLE_SENTINEL; + //pEdges[maxEdge].m_handle = 0; int minEdge = pHandle->m_minEdges[axis]; - pEdges[minEdge].m_pos = BP_HANDLE_SENTINEL; + //pEdges[minEdge].m_pos = BP_HANDLE_SENTINEL; + //pEdges[minEdge].m_handle = 0; } // remove the edges by sorting them up to the end of the list @@ -234,17 +272,25 @@ void btAxisSweep3::removeHandle(BP_FP_INT_TYPE handle) pEdges[max].m_pos = BP_HANDLE_SENTINEL; sortMaxUp(axis,max,false); - + + BP_FP_INT_TYPE i = pHandle->m_minEdges[axis]; pEdges[i].m_pos = BP_HANDLE_SENTINEL; + sortMinUp(axis,i,false); pEdges[limit-1].m_handle = 0; pEdges[limit-1].m_pos = BP_HANDLE_SENTINEL; + +#ifdef DEBUG_BROADPHASE + debugPrintAxis(axis,false); +#endif //DEBUG_BROADPHASE + } + // free the handle freeHandle(handle); @@ -365,7 +411,7 @@ bool btAxisSweep3::testOverlap(int ignoreAxis,const Handle* pHandleA, const Hand } } - //optimization 2: only 2 axis need to be tested + //optimization 2: only 2 axis need to be tested (conflicts with 'delayed removal' optimization) /*for (int axis = 0; axis < 3; axis++) { @@ -417,14 +463,22 @@ void btAxisSweep3::updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,c if (dmax < 0) sortMaxDown(axis, emax); + +#ifdef DEBUG_BROADPHASE + debugPrintAxis(axis); +#endif //DEBUG_BROADPHASE } - //PrintAxis(1); + } + + + // sorting a min edge downwards can only ever *add* overlaps void btAxisSweep3::sortMinDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps) { + Edge* pEdge = m_pEdges[axis] + edge; Edge* pPrev = pEdge - 1; Handle* pHandleEdge = getHandle(pEdge->m_handle); @@ -461,6 +515,11 @@ void btAxisSweep3::sortMinDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlap pEdge--; pPrev--; } + +#ifdef DEBUG_BROADPHASE + debugPrintAxis(axis); +#endif //DEBUG_BROADPHASE + } // sorting a min edge upwards can only ever *remove* overlaps @@ -470,7 +529,7 @@ void btAxisSweep3::sortMinUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps) Edge* pNext = pEdge + 1; Handle* pHandleEdge = getHandle(pEdge->m_handle); - while (pEdge->m_pos > pNext->m_pos) + while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos)) { Handle* pHandleNext = getHandle(pNext->m_handle); @@ -505,11 +564,14 @@ void btAxisSweep3::sortMinUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps) pEdge++; pNext++; } + + } // sorting a max edge downwards can only ever *remove* overlaps void btAxisSweep3::sortMaxDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps) { + Edge* pEdge = m_pEdges[axis] + edge; Edge* pPrev = pEdge - 1; Handle* pHandleEdge = getHandle(pEdge->m_handle); @@ -555,6 +617,12 @@ void btAxisSweep3::sortMaxDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlap pEdge--; pPrev--; } + + +#ifdef DEBUG_BROADPHASE + debugPrintAxis(axis); +#endif //DEBUG_BROADPHASE + } // sorting a max edge upwards can only ever *add* overlaps @@ -564,7 +632,7 @@ void btAxisSweep3::sortMaxUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps) Edge* pNext = pEdge + 1; Handle* pHandleEdge = getHandle(pEdge->m_handle); - while (pEdge->m_pos > pNext->m_pos) + while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos)) { Handle* pHandleNext = getHandle(pNext->m_handle); @@ -595,4 +663,5 @@ void btAxisSweep3::sortMaxUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps) pEdge++; pNext++; } + } diff --git a/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h b/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h index 90cd35438..cae241904 100644 --- a/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h +++ b/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h @@ -31,14 +31,15 @@ #define BP_FP_INT_TYPE unsigned int #define BP_MAX_HANDLES 1500000 //arbitrary maximum number of handles #define BP_HANDLE_SENTINEL 0xffffffff - #define BP_HANDLE_MASK 0xfffffffc + #define BP_HANDLE_MASK 0xfffffffe #else #define BP_FP_INT_TYPE unsigned short int #define BP_MAX_HANDLES 32767 #define BP_HANDLE_SENTINEL 0xffff #define BP_HANDLE_MASK 0xfffe -#endif +#endif //BP_USE_FIXEDPOINT_INT_32 +//#define DEBUG_BROADPHASE 1 /// btAxisSweep3 is an efficient implementation of the 3d axis sweep and prune broadphase. /// It uses arrays rather then lists for storage of the 3 axis. Also it operates using integer coordinates instead of floats. @@ -97,6 +98,9 @@ private: bool testOverlap(int ignoreAxis,const Handle* pHandleA, const Handle* pHandleB); +#ifdef DEBUG_BROADPHASE + void debugPrintAxis(int axis,bool checkCardinality=true); +#endif //DEBUG_BROADPHASE //Overlap* AddOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB); //void RemoveOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB); diff --git a/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp b/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp index 43b06e080..8da554ef1 100644 --- a/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp +++ b/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp @@ -164,9 +164,7 @@ void btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling) { btTriangleMeshShape::setLocalScaling(scaling); delete m_bvh; - ///rescale aabb, instead of calculating? - m_localAabbMin*=scaling; - m_localAabbMax*=scaling; + ///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work m_bvh = new btOptimizedBvh(); //rebuild the bvh... m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax); diff --git a/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp b/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp index 0b4607980..22c8fdd9a 100644 --- a/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp +++ b/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp @@ -195,5 +195,11 @@ void btConvexTriangleMeshShape::setLocalScaling(const btVector3& scaling) m_stridingMesh->setScaling(scaling); recalcLocalAabb(); + } + +const btVector3& btConvexTriangleMeshShape::getLocalScaling() const +{ + return m_stridingMesh->getScaling(); +} \ No newline at end of file diff --git a/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h b/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h index a0db2797b..1142bd84d 100644 --- a/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h +++ b/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h @@ -39,7 +39,8 @@ public: virtual bool isInside(const btPoint3& pt,btScalar tolerance) const; - void setLocalScaling(const btVector3& scaling); + virtual void setLocalScaling(const btVector3& scaling); + virtual const btVector3& getLocalScaling() const; }; diff --git a/src/BulletDynamics/Vehicle/btRaycastVehicle.h b/src/BulletDynamics/Vehicle/btRaycastVehicle.h index 2597273c0..e185447a3 100644 --- a/src/BulletDynamics/Vehicle/btRaycastVehicle.h +++ b/src/BulletDynamics/Vehicle/btRaycastVehicle.h @@ -142,6 +142,26 @@ public: return m_indexForwardAxis; } + + ///Worldspace forward vector + btVector3 getForwardVector() const + { + const btTransform& chassisTrans = getChassisWorldTransform(); + + btVector3 forwardW ( + chassisTrans.getBasis()[0][m_indexForwardAxis], + chassisTrans.getBasis()[1][m_indexForwardAxis], + chassisTrans.getBasis()[2][m_indexForwardAxis]); + + return forwardW; + } + + ///Velocity of vehicle (positive if velocity vector has same direction as foward vector) + btScalar getCurrentSpeedKmHour() const + { + return m_currentVehicleSpeedKmHour; + } + virtual void setCoordinateSystem(int rightIndex,int upIndex,int forwardIndex) { m_indexRightAxis = rightIndex; diff --git a/src/LinearMath/btMatrix3x3.h b/src/LinearMath/btMatrix3x3.h index e9d6e6795..b40c6805a 100644 --- a/src/LinearMath/btMatrix3x3.h +++ b/src/LinearMath/btMatrix3x3.h @@ -232,13 +232,7 @@ class btMatrix3x3 { } } - btVector3 getScaling() const - { - return btVector3(m_el[0][0] * m_el[0].x() + m_el[1].x() * m_el[1].x() + m_el[2].x() * m_el[2].x(), - m_el[0].y() * m_el[0].y() + m_el[1].y() * m_el[1].y() + m_el[2].y() * m_el[2].y(), - m_el[0].z() * m_el[0].z() + m_el[1].z() * m_el[1].z() + m_el[2].z() * m_el[2].z()); - } - + btMatrix3x3 scaled(const btVector3& s) const {