updating bullet
authorDaniel Genrich <daniel.genrich@gmx.net>
Tue, 6 Nov 2007 14:26:08 +0000 (14:26 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Tue, 6 Nov 2007 14:26:08 +0000 (14:26 +0000)
173 files changed:
extern/bullet2/src/Bullet-C-Api.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp
extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp [new file with mode: 0644]
extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h [new file with mode: 0644]
extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp
extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h
extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h [new file with mode: 0644]
extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h
extern/bullet2/src/BulletCollision/CMakeLists.txt
extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h
extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.h
extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h
extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp [new file with mode: 0644]
extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h [new file with mode: 0644]
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h
extern/bullet2/src/BulletCollision/ibmsdk/Makefile [new file with mode: 0644]
extern/bullet2/src/BulletDynamics/CMakeLists.txt
extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h
extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp
extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h
extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp [new file with mode: 0644]
extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp [new file with mode: 0644]
extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.h [new file with mode: 0644]
extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h
extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp
extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h
extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp
extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h
extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp
extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h
extern/bullet2/src/BulletDynamics/Vehicle/btVehicleRaycaster.h
extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.h
extern/bullet2/src/BulletDynamics/ibmsdk/Makefile [new file with mode: 0644]
extern/bullet2/src/LinearMath/CMakeLists.txt
extern/bullet2/src/LinearMath/btAabbUtil2.h
extern/bullet2/src/LinearMath/btAlignedAllocator.cpp
extern/bullet2/src/LinearMath/btAlignedAllocator.h
extern/bullet2/src/LinearMath/btAlignedObjectArray.h
extern/bullet2/src/LinearMath/btIDebugDraw.h
extern/bullet2/src/LinearMath/btMatrix3x3.h
extern/bullet2/src/LinearMath/btMinMax.h
extern/bullet2/src/LinearMath/btPoolAllocator.h [new file with mode: 0755]
extern/bullet2/src/LinearMath/btQuadWord.h
extern/bullet2/src/LinearMath/btQuaternion.h
extern/bullet2/src/LinearMath/btScalar.h
extern/bullet2/src/LinearMath/btStackAlloc.h
extern/bullet2/src/LinearMath/btTransform.h
extern/bullet2/src/LinearMath/btTransformUtil.h
extern/bullet2/src/LinearMath/btVector3.h
extern/bullet2/src/LinearMath/ibmsdk/Makefile [new file with mode: 0644]
extern/bullet2/src/SConscript
extern/bullet2/src/btBulletCollisionCommon.h
extern/bullet2/src/btBulletDynamicsCommon.h
extern/bullet2/src/ibmsdk/Makefile [new file with mode: 0644]

index ccb0c452f3e0d15ebf2875f4ee75e0ff311f434e..45a4f68485803c7cb874dc40d848127f9d607f51 100644 (file)
-#ifndef Bullet_C_API_H
-#define Bullet_C_API_H
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+       Draft high-level generic physics C-API. For low-level access, use the physics SDK native API's.
+       Work in progress, functionality will be added on demand.
+
+       If possible, use the richer Bullet C++ API, by including "btBulletDynamicsCommon.h"
+*/
+
+#ifndef BULLET_C_API_H
+#define BULLET_C_API_H
+
+#define PL_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
+
+#ifdef BT_USE_DOUBLE_PRECISION
+typedef double plReal;
+#else
+typedef float  plReal;
+#endif
+
+typedef plReal plVector3[3];
+typedef plReal plQuaternion[4];
 
 #ifdef __cplusplus
-extern "C"  {
-#endif // __cplusplus
+extern "C" { 
+#endif
+
+/*     Particular physics SDK */
+       PL_DECLARE_HANDLE(plPhysicsSdkHandle);
+
+/*     Dynamics world, belonging to some physics SDK */
+       PL_DECLARE_HANDLE(plDynamicsWorldHandle);
+
+/* Rigid Body that can be part of a Dynamics World */  
+       PL_DECLARE_HANDLE(plRigidBodyHandle);
+
+/*     Collision Shape/Geometry, property of a Rigid Body */
+       PL_DECLARE_HANDLE(plCollisionShapeHandle);
+
+/* Constraint for Rigid Bodies */
+       PL_DECLARE_HANDLE(plConstraintHandle);
+
+/* Triangle Mesh interface */
+       PL_DECLARE_HANDLE(plMeshInterfaceHandle);
+
+/* Broadphase Scene/Proxy Handles */
+       PL_DECLARE_HANDLE(plCollisionBroadphaseHandle);
+       PL_DECLARE_HANDLE(plBroadphaseProxyHandle);
+       PL_DECLARE_HANDLE(plCollisionWorldHandle);
+
+/*
+       Create and Delete a Physics SDK 
+*/
+
+       extern  plPhysicsSdkHandle      plNewBulletSdk(); //this could be also another sdk, like ODE, PhysX etc.
+       extern  void            plDeletePhysicsSdk(plPhysicsSdkHandle   physicsSdk);
+
+/* Collision World, not strictly necessary, you can also just create a Dynamics World with Rigid Bodies which internally manages the Collision World with Collision Objects */
+
+       typedef void(*btBroadphaseCallback)(void* clientData, void* object1,void* object2);
+
+       extern plCollisionBroadphaseHandle      plCreateSapBroadphase(btBroadphaseCallback beginCallback,btBroadphaseCallback endCallback);
+
+       extern void     plDestroyBroadphase(plCollisionBroadphaseHandle bp);
+
+       extern  plBroadphaseProxyHandle plCreateProxy(plCollisionBroadphaseHandle bp, void* clientData, plReal minX,plReal minY,plReal minZ, plReal maxX,plReal maxY, plReal maxZ);
+
+       extern void plDestroyProxy(plCollisionBroadphaseHandle bp, plBroadphaseProxyHandle proxyHandle);
+
+       extern void plSetBoundingBox(plBroadphaseProxyHandle proxyHandle, plReal minX,plReal minY,plReal minZ, plReal maxX,plReal maxY, plReal maxZ);
+
+/* todo: add pair cache support with queries like add/remove/find pair */
+       
+       extern plCollisionWorldHandle plCreateCollisionWorld(plPhysicsSdkHandle physicsSdk);
+
+/* todo: add/remove objects */
+       
+
+/* Dynamics World */
+
+       extern  plDynamicsWorldHandle plCreateDynamicsWorld(plPhysicsSdkHandle physicsSdk);
+
+       extern  void           plDeleteDynamicsWorld(plDynamicsWorldHandle world);
+
+       extern  void    plStepSimulation(plDynamicsWorldHandle, plReal  timeStep);
+
+       extern  void plAddRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object);
+
+       extern  void plRemoveRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object);
+
+
+/* Rigid Body  */
+
+       extern  plRigidBodyHandle plCreateRigidBody(    void* user_data,  float mass, plCollisionShapeHandle cshape );
+
+       extern  void plDeleteRigidBody(plRigidBodyHandle body);
+
+
+/* Collision Shape definition */
+
+       extern  plCollisionShapeHandle plNewSphereShape(plReal radius);
+       extern  plCollisionShapeHandle plNewBoxShape(plReal x, plReal y, plReal z);
+       extern  plCollisionShapeHandle plNewCapsuleShape(plReal radius, plReal height); 
+       extern  plCollisionShapeHandle plNewConeShape(plReal radius, plReal height);
+       extern  plCollisionShapeHandle plNewCylinderShape(plReal radius, plReal height);
+       extern  plCollisionShapeHandle plNewCompoundShape();
+       extern  void    plAddChildShape(plCollisionShapeHandle compoundShape,plCollisionShapeHandle childShape, plVector3 childPos,plQuaternion childOrn);
+
+       extern  void plDeleteShape(plCollisionShapeHandle shape);
+
+       /* Convex Meshes */
+       extern  plCollisionShapeHandle plNewConvexHullShape();
+       extern  void            plAddVertex(plCollisionShapeHandle convexHull, plReal x,plReal y,plReal z);
+/* Concave static triangle meshes */
+       extern  plMeshInterfaceHandle              plNewMeshInterface();
+       extern  void            plAddTriangle(plMeshInterfaceHandle meshHandle, plVector3 v0,plVector3 v1,plVector3 v2);
+       extern  plCollisionShapeHandle plNewStaticTriangleMeshShape(plMeshInterfaceHandle);
+
+       extern  void plSetScaling(plCollisionShapeHandle shape, plVector3 scaling);
+
+/* SOLID has Response Callback/Table/Management */
+/* PhysX has Triggers, User Callbacks and filtering */
+/* ODE has the typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2); */
+
+/*     typedef void plUpdatedPositionCallback(void* userData, plRigidBodyHandle        rbHandle, plVector3 pos); */
+/*     typedef void plUpdatedOrientationCallback(void* userData, plRigidBodyHandle     rbHandle, plQuaternion orientation); */
+
+       /* get world transform */
+       extern void     plGetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix);
+       extern void     plGetPosition(plRigidBodyHandle object,plVector3 position);
+       extern void plGetOrientation(plRigidBodyHandle object,plQuaternion orientation);
+
+       /* set world transform (position/orientation) */
+       extern  void plSetPosition(plRigidBodyHandle object, const plVector3 position);
+       extern  void plSetOrientation(plRigidBodyHandle object, const plQuaternion orientation);
+       extern  void plSetEuler(plReal yaw,plReal pitch,plReal roll, plQuaternion orient);
+
+       typedef struct plRayCastResult {
+               plRigidBodyHandle               m_body;  
+               plCollisionShapeHandle  m_shape;                
+               plVector3                               m_positionWorld;                
+               plVector3                               m_normalWorld;
+       } plRayCastResult;
+
+       extern  int plRayCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plRayCastResult res);
+
+       /* Sweep API */
+
+       /* extern  plRigidBodyHandle plObjectCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal); */
+
+       /* Continuous Collision Detection API */
 
 double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]);
 
 #ifdef __cplusplus
 }
-#endif // __cplusplus
-
 #endif
 
+#endif //BULLET_C_API_H
+
index be4a11506df48388820989d28d4b48a67d735e8a..d7eea33ea416d17b2c7dc8f5a373f1f29229daa6 100644 (file)
 
 #include <assert.h>
 
-#ifdef DEBUG_BROADPHASE
-#include <stdio.h>
-void btAxisSweep3::debugPrintAxis(int axis, bool checkCardinality)
+btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache)
+:btAxisSweep3Internal<unsigned short int>(worldAabbMin,worldAabbMax,0xfffe,0xffff,maxHandles,pairCache)
 {
-       int numEdges = m_pHandles[0].m_maxEdges[axis];
-       printf("SAP Axis %d, numEdges=%d\n",axis,numEdges);
-
-       int i;
-       for (i=0;i<numEdges+1;i++)
-       {
-               Edge* pEdge = m_pEdges[axis] + i;
-               Handle* pHandlePrev = getHandle(pEdge->m_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;
-               BP_FP_INT_TYPE handleId = addHandle(min,max, userPtr,collisionFilterGroup,collisionFilterMask);
-               
-               Handle* handle = getHandle(handleId);
-                               
-               return handle;
-}
-
-void   btAxisSweep3::destroyProxy(btBroadphaseProxy* proxy)
-{
-       Handle* handle = static_cast<Handle*>(proxy);
-       removeHandle(handle->m_handleId);
-}
-
-void   btAxisSweep3::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax)
-{
-       Handle* handle = static_cast<Handle*>(proxy);
-       updateHandle(handle->m_handleId,aabbMin,aabbMax);
-
-}
-
-
-
-
-
-
-btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, int maxHandles)
-:btOverlappingPairCache()
-{
-       m_invalidPair = 0;
-       //assert(bounds.HasVolume());
-
        // 1 handle is reserved as sentinel
-       btAssert(maxHandles > 1 && maxHandles < BP_MAX_HANDLES);
-
-       // init bounds
-       m_worldAabbMin = worldAabbMin;
-       m_worldAabbMax = worldAabbMax;
-
-       btVector3 aabbSize = m_worldAabbMax - m_worldAabbMin;
-
-       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];
-       m_maxHandles = maxHandles;
-       m_numHandles = 0;
-
-       // handle 0 is reserved as the null index, and is also used as the sentinel
-       m_firstFreeHandle = 1;
-       {
-               for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < maxHandles; i++)
-                       m_pHandles[i].SetNextFree(i + 1);
-               m_pHandles[maxHandles - 1].SetNextFree(0);
-       }
-
-       {
-       // allocate edge buffers
-       for (int i = 0; i < 3; i++)
-               m_pEdges[i] = new Edge[maxHandles * 2];
-       }
-       //removed overlap management
-
-       // make boundary sentinels
-       
-       m_pHandles[0].m_clientObject = 0;
-
-       for (int axis = 0; axis < 3; axis++)
-       {
-               m_pHandles[0].m_minEdges[axis] = 0;
-               m_pHandles[0].m_maxEdges[axis] = 1;
-
-               m_pEdges[axis][0].m_pos = 0;
-               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()
-{
-       
-       for (int i = 2; i >= 0; i--)
-               delete[] m_pEdges[i];
-       delete[] m_pHandles;
-}
-
-void btAxisSweep3::quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const
-{
-       btPoint3 clampedPoint(point);
-       
-
-
-       clampedPoint.setMax(m_worldAabbMin);
-       clampedPoint.setMin(m_worldAabbMax);
-
-       btVector3 v = (clampedPoint - m_worldAabbMin) * m_quantize;
-       out[0] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getX() & BP_HANDLE_MASK) | isMax);
-       out[1] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getY() & BP_HANDLE_MASK) | isMax);
-       out[2] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getZ() & BP_HANDLE_MASK) | isMax);
-       
-}
-
-
-
-BP_FP_INT_TYPE btAxisSweep3::allocHandle()
-{
-       assert(m_firstFreeHandle);
-
-       BP_FP_INT_TYPE handle = m_firstFreeHandle;
-       m_firstFreeHandle = getHandle(handle)->GetNextFree();
-       m_numHandles++;
-
-       return handle;
-}
-
-void btAxisSweep3::freeHandle(BP_FP_INT_TYPE handle)
-{
-       assert(handle > 0 && handle < m_maxHandles);
-
-       getHandle(handle)->SetNextFree(m_firstFreeHandle);
-       m_firstFreeHandle = handle;
-
-       m_numHandles--;
-}
-
-
-
-BP_FP_INT_TYPE btAxisSweep3::addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask)
-{
-       // quantize the bounds
-       BP_FP_INT_TYPE min[3], max[3];
-       quantize(min, aabbMin, 0);
-       quantize(max, aabbMax, 1);
-
-       // allocate a handle
-       BP_FP_INT_TYPE handle = allocHandle();
-       assert(handle!= 0xcdcd);
-
-       Handle* pHandle = getHandle(handle);
-       
-       pHandle->m_handleId = handle;
-       //pHandle->m_pOverlaps = 0;
-       pHandle->m_clientObject = pOwner;
-       pHandle->m_collisionFilterGroup = collisionFilterGroup;
-       pHandle->m_collisionFilterMask = collisionFilterMask;
-
-       // 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];
-
-               m_pEdges[axis][limit - 1].m_pos = min[axis];
-               m_pEdges[axis][limit - 1].m_handle = handle;
-
-               m_pEdges[axis][limit].m_pos = max[axis];
-               m_pEdges[axis][limit].m_handle = handle;
-
-               pHandle->m_minEdges[axis] = limit - 1;
-               pHandle->m_maxEdges[axis] = limit;
-       }
-
-       // now sort the new edges to their correct position
-       sortMinDown(0, pHandle->m_minEdges[0], false);
-       sortMaxDown(0, pHandle->m_maxEdges[0], false);
-       sortMinDown(1, pHandle->m_minEdges[1], false);
-       sortMaxDown(1, pHandle->m_maxEdges[1], false);
-       sortMinDown(2, pHandle->m_minEdges[2], true);
-       sortMaxDown(2, pHandle->m_maxEdges[2], true);
-
-
-       return handle;
-}
-
-
-void btAxisSweep3::removeHandle(BP_FP_INT_TYPE handle)
-{
-       
-       Handle* pHandle = getHandle(handle);
-
-       //explicitly remove the pairs containing the proxy
-       //we could do it also in the sortMinUp (passing true)
-       //todo: compare performance
-       removeOverlappingPairsContainingProxy(pHandle);
-
-
-       // compute current limit of edge arrays
-       int limit = m_numHandles * 2;
-       
-       int axis;
-
-       for (axis = 0;axis<3;axis++)
-       {
-               m_pHandles[0].m_maxEdges[axis] -= 2;
-       }
-
-       // remove the edges by sorting them up to the end of the list
-       for ( axis = 0; axis < 3; axis++)
-       {
-               Edge* pEdges = m_pEdges[axis];
-               BP_FP_INT_TYPE max = pHandle->m_maxEdges[axis];
-               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);
-
-       
-}
-
-extern int gOverlappingPairs;
-
-
-void   btAxisSweep3::refreshOverlappingPairs()
-{
-
-}
-void   btAxisSweep3::processAllOverlappingPairs(btOverlapCallback* callback)
-{
-
-       //perform a sort, to find duplicates and to sort 'invalid' pairs to the end
-       m_overlappingPairArray.heapSort(btBroadphasePairSortPredicate());
-
-       //remove the 'invalid' ones
-#ifdef USE_POPBACK_REMOVAL
-       while (m_invalidPair>0)
-       {
-               m_invalidPair--;
-               m_overlappingPairArray.pop_back();
-       }
-#else  
-       m_overlappingPairArray.resize(m_overlappingPairArray.size() - m_invalidPair);
-       m_invalidPair = 0;
-#endif
-
-       
-       int i;
-
-       btBroadphasePair previousPair;
-       previousPair.m_pProxy0 = 0;
-       previousPair.m_pProxy1 = 0;
-       previousPair.m_algorithm = 0;
-       
-       
-       for (i=0;i<m_overlappingPairArray.size();i++)
-       {
-       
-               btBroadphasePair& pair = m_overlappingPairArray[i];
-
-               bool isDuplicate = (pair == previousPair);
-
-               previousPair = pair;
-
-               bool needsRemoval = false;
-
-               if (!isDuplicate)
-               {
-                       bool hasOverlap = testOverlap(pair.m_pProxy0,pair.m_pProxy1);
-
-                       if (hasOverlap)
-                       {
-                               needsRemoval = callback->processOverlap(pair);
-                       } else
-                       {
-                               needsRemoval = true;
-                       }
-               } else
-               {
-                       //remove duplicate
-                       needsRemoval = true;
-                       //should have no algorithm
-                       btAssert(!pair.m_algorithm);
-               }
-               
-               if (needsRemoval)
-               {
-                       cleanOverlappingPair(pair);
-
-       //              m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
-       //              m_overlappingPairArray.pop_back();
-                       pair.m_pProxy0 = 0;
-                       pair.m_pProxy1 = 0;
-                       m_invalidPair++;
-                       gOverlappingPairs--;
-               } 
-               
-       }
-}
-
-
-bool btAxisSweep3::testOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
-{
-       const Handle* pHandleA = static_cast<Handle*>(proxy0);
-       const Handle* pHandleB = static_cast<Handle*>(proxy1);
-       
-       //optimization 1: check the array index (memory address), instead of the m_pos
-
-       for (int axis = 0; axis < 3; axis++)
-       { 
-               if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] || 
-                       pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis]) 
-               { 
-                       return false; 
-               } 
-       } 
-       return true;
-}
-
-bool btAxisSweep3::testOverlap(int ignoreAxis,const Handle* pHandleA, const Handle* pHandleB)
-{
-       //optimization 1: check the array index (memory address), instead of the m_pos
-
-       for (int axis = 0; axis < 3; axis++)
-       { 
-               if (axis != ignoreAxis)
-               {
-                       if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] || 
-                               pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis]) 
-                       { 
-                               return false; 
-                       } 
-               }
-       } 
-
-       //optimization 2: only 2 axis need to be tested (conflicts with 'delayed removal' optimization)
-
-       /*for (int axis = 0; axis < 3; axis++)
-       {
-               if (m_pEdges[axis][pHandleA->m_maxEdges[axis]].m_pos < m_pEdges[axis][pHandleB->m_minEdges[axis]].m_pos ||
-                       m_pEdges[axis][pHandleB->m_maxEdges[axis]].m_pos < m_pEdges[axis][pHandleA->m_minEdges[axis]].m_pos)
-               {
-                       return false;
-               }
-       }
-       */
-
-       return true;
-}
-
-void btAxisSweep3::updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax)
-{
-//     assert(bounds.IsFinite());
-       //assert(bounds.HasVolume());
-
-       Handle* pHandle = getHandle(handle);
-
-       // quantize the new bounds
-       BP_FP_INT_TYPE min[3], max[3];
-       quantize(min, aabbMin, 0);
-       quantize(max, aabbMax, 1);
-
-       // update changed edges
-       for (int axis = 0; axis < 3; axis++)
-       {
-               BP_FP_INT_TYPE emin = pHandle->m_minEdges[axis];
-               BP_FP_INT_TYPE emax = pHandle->m_maxEdges[axis];
-
-               int dmin = (int)min[axis] - (int)m_pEdges[axis][emin].m_pos;
-               int dmax = (int)max[axis] - (int)m_pEdges[axis][emax].m_pos;
-
-               m_pEdges[axis][emin].m_pos = min[axis];
-               m_pEdges[axis][emax].m_pos = max[axis];
-
-               // expand (only adds overlaps)
-               if (dmin < 0)
-                       sortMinDown(axis, emin);
-
-               if (dmax > 0)
-                       sortMaxUp(axis, emax);
-
-               // shrink (only removes overlaps)
-               if (dmin > 0)
-                       sortMinUp(axis, emin);
-
-               if (dmax < 0)
-                       sortMaxDown(axis, emax);
-
-#ifdef DEBUG_BROADPHASE
-       debugPrintAxis(axis);
-#endif //DEBUG_BROADPHASE
-       }
-
-       
-}
-
-
-
-
-// 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);
-
-       while (pEdge->m_pos < pPrev->m_pos)
-       {
-               Handle* pHandlePrev = getHandle(pPrev->m_handle);
-
-               if (pPrev->IsMax())
-               {
-                       // if previous edge is a maximum check the bounds and add an overlap if necessary
-                       if (updateOverlaps && testOverlap(axis,pHandleEdge, pHandlePrev))
-                       {
-                               addOverlappingPair(pHandleEdge,pHandlePrev);
-
-                               //AddOverlap(pEdge->m_handle, pPrev->m_handle);
-
-                       }
-
-                       // update edge reference in other handle
-                       pHandlePrev->m_maxEdges[axis]++;
-               }
-               else
-                       pHandlePrev->m_minEdges[axis]++;
-
-               pHandleEdge->m_minEdges[axis]--;
-
-               // swap the edges
-               Edge swap = *pEdge;
-               *pEdge = *pPrev;
-               *pPrev = swap;
-
-               // decrement
-               pEdge--;
-               pPrev--;
-       }
-
-#ifdef DEBUG_BROADPHASE
-       debugPrintAxis(axis);
-#endif //DEBUG_BROADPHASE
-
-}
-
-// sorting a min edge upwards can only ever *remove* overlaps
-void btAxisSweep3::sortMinUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps)
-{
-       Edge* pEdge = m_pEdges[axis] + edge;
-       Edge* pNext = pEdge + 1;
-       Handle* pHandleEdge = getHandle(pEdge->m_handle);
-
-       while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos))
-       {
-               Handle* pHandleNext = getHandle(pNext->m_handle);
-
-               if (pNext->IsMax())
-               {
-                       // if next edge is maximum remove any overlap between the two handles
-                       if (updateOverlaps)
-                       {
-                               /*
-                               Handle* handle0 = getHandle(pEdge->m_handle);
-                               Handle* handle1 = getHandle(pNext->m_handle);
-                               btBroadphasePair tmpPair(*handle0,*handle1);
-                               removeOverlappingPair(tmpPair);
-                               */
-
-                       }
-
-                       // update edge reference in other handle
-                       pHandleNext->m_maxEdges[axis]--;
-               }
-               else
-                       pHandleNext->m_minEdges[axis]--;
-
-               pHandleEdge->m_minEdges[axis]++;
-
-               // swap the edges
-               Edge swap = *pEdge;
-               *pEdge = *pNext;
-               *pNext = swap;
-
-               // increment
-               pEdge++;
-               pNext++;
-       }
-
+       btAssert(maxHandles > 1 && maxHandles < 32767);
 
 }
 
-// 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);
-
-       while (pEdge->m_pos < pPrev->m_pos)
-       {
-               Handle* pHandlePrev = getHandle(pPrev->m_handle);
-
-               if (!pPrev->IsMax())
-               {
-                       // if previous edge was a minimum remove any overlap between the two handles
-                       if (updateOverlaps)
-                       {
-                               //this is done during the overlappingpairarray iteration/narrowphase collision
-                               /*
-                               Handle* handle0 = getHandle(pEdge->m_handle);
-                               Handle* handle1 = getHandle(pPrev->m_handle);
-                               btBroadphasePair* pair = findPair(handle0,handle1);
-                               //assert(pair);
-
-                               if (pair)
-                               {
-                                       removeOverlappingPair(*pair);
-                               }
-                               */
-
-                       }
-
-                       // update edge reference in other handle
-                       pHandlePrev->m_minEdges[axis]++;;
-               }
-               else
-                       pHandlePrev->m_maxEdges[axis]++;
-
-               pHandleEdge->m_maxEdges[axis]--;
-
-               // swap the edges
-               Edge swap = *pEdge;
-               *pEdge = *pPrev;
-               *pPrev = swap;
 
-               // decrement
-               pEdge--;
-               pPrev--;
-       }
-
-       
-#ifdef DEBUG_BROADPHASE
-       debugPrintAxis(axis);
-#endif //DEBUG_BROADPHASE
-
-}
-
-// sorting a max edge upwards can only ever *add* overlaps
-void btAxisSweep3::sortMaxUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps)
+bt32BitAxisSweep3::bt32BitAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles , btOverlappingPairCache* pairCache )
+:btAxisSweep3Internal<unsigned int>(worldAabbMin,worldAabbMax,0xfffffffe,0x7fffffff,maxHandles,pairCache)
 {
-       Edge* pEdge = m_pEdges[axis] + edge;
-       Edge* pNext = pEdge + 1;
-       Handle* pHandleEdge = getHandle(pEdge->m_handle);
-
-       while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos))
-       {
-               Handle* pHandleNext = getHandle(pNext->m_handle);
-
-               if (!pNext->IsMax())
-               {
-                       // if next edge is a minimum check the bounds and add an overlap if necessary
-                       if (updateOverlaps && testOverlap(axis, pHandleEdge, pHandleNext))
-                       {
-                               Handle* handle0 = getHandle(pEdge->m_handle);
-                               Handle* handle1 = getHandle(pNext->m_handle);
-                               addOverlappingPair(handle0,handle1);
-                       }
-
-                       // update edge reference in other handle
-                       pHandleNext->m_minEdges[axis]--;
-               }
-               else
-                       pHandleNext->m_maxEdges[axis]--;
-
-               pHandleEdge->m_maxEdges[axis]++;
-
-               // swap the edges
-               Edge swap = *pEdge;
-               *pEdge = *pNext;
-               *pNext = swap;
-
-               // increment
-               pEdge++;
-               pNext++;
-       }
-       
+       // 1 handle is reserved as sentinel
+       btAssert(maxHandles > 1 && maxHandles < 2147483647);
 }
index 57bbb36867225297c866ed1618b94193f61c6584..d36df6e66217d0fb6f70fb82e01fa99adfdf5864 100644 (file)
 #ifndef AXIS_SWEEP_3_H
 #define AXIS_SWEEP_3_H
 
-#include "../../LinearMath/btPoint3.h"
-#include "../../LinearMath/btVector3.h"
+#include "LinearMath/btPoint3.h"
+#include "LinearMath/btVector3.h"
 #include "btOverlappingPairCache.h"
+#include "btBroadphaseInterface.h"
 #include "btBroadphaseProxy.h"
-
-
-//Enable BP_USE_FIXEDPOINT_INT_32 if you need more then 32767 objects
-//#define BP_USE_FIXEDPOINT_INT_32 1
-
-#ifdef BP_USE_FIXEDPOINT_INT_32
-       #define BP_FP_INT_TYPE unsigned int
-       #define BP_MAX_HANDLES 1500000 //arbitrary maximum number of handles
-       #define BP_HANDLE_SENTINEL 0x7fffffff
-       #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 //BP_USE_FIXEDPOINT_INT_32
+#include "btOverlappingPairCallback.h"
 
 //#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.
-/// The testOverlap check is optimized to check the array index, rather then the actual AABB coordinates/pos
-class btAxisSweep3 : public btOverlappingPairCache
+/// btAxisSweep3Internal is an internal template class that implements sweep and prune.
+/// Dont use this class directly, use btAxisSweep3 or bt32BitAxisSweep3 instead.
+template <typename BP_FP_INT_TYPE>
+class btAxisSweep3Internal : public btBroadphaseInterface
 {
+protected:
+
+       BP_FP_INT_TYPE  m_bpHandleMask;
+       BP_FP_INT_TYPE  m_handleSentinel;
 
 public:
        
@@ -61,36 +51,44 @@ public:
        };
 
 public:
-       class Handle : public btBroadphaseProxy
+       ATTRIBUTE_ALIGNED16(class) Handle : public btBroadphaseProxy
        {
        public:
-               
+       BT_DECLARE_ALIGNED_ALLOCATOR();
+       
                // indexes into the edge arrays
                BP_FP_INT_TYPE m_minEdges[3], m_maxEdges[3];            // 6 * 2 = 12
-               BP_FP_INT_TYPE m_handleId;
+//             BP_FP_INT_TYPE m_uniqueId;
                BP_FP_INT_TYPE m_pad;
                
                //void* m_pOwner; this is now in btBroadphaseProxy.m_clientObject
        
-               inline void SetNextFree(BP_FP_INT_TYPE next) {m_minEdges[0] = next;}
-               inline BP_FP_INT_TYPE GetNextFree() const {return m_minEdges[0];}
+               SIMD_FORCE_INLINE void SetNextFree(BP_FP_INT_TYPE next) {m_minEdges[0] = next;}
+               SIMD_FORCE_INLINE BP_FP_INT_TYPE GetNextFree() const {return m_minEdges[0];}
        };              // 24 bytes + 24 for Edge structures = 44 bytes total per entry
 
        
-private:
+protected:
        btPoint3 m_worldAabbMin;                                                // overall system bounds
        btPoint3 m_worldAabbMax;                                                // overall system bounds
 
        btVector3 m_quantize;                                           // scaling factor for quantization
 
        BP_FP_INT_TYPE m_numHandles;                                            // number of active handles
-       int m_maxHandles;                                               // max number of handles
+       BP_FP_INT_TYPE m_maxHandles;                                            // max number of handles
        Handle* m_pHandles;                                             // handles pool
        BP_FP_INT_TYPE m_firstFreeHandle;               // free handles list
 
        Edge* m_pEdges[3];                                              // edge arrays for the 3 axes (each array has m_maxHandles * 2 + 2 sentinel entries)
 
-       int m_invalidPair;
+       btOverlappingPairCache* m_pairCache;
+
+       ///btOverlappingPairCallback is an additional optional user callback for adding/removing overlapping pairs, similar interface to btOverlappingPairCache.
+       btOverlappingPairCallback* m_userPairCallback;
+       
+       bool    m_ownsPairCache;
+
+       int     m_invalidPair;
 
        // allocation/deallocation
        BP_FP_INT_TYPE allocHandle();
@@ -108,29 +106,773 @@ private:
 
        void quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const;
 
-       void sortMinDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true);
-       void sortMinUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true);
-       void sortMaxDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true);
-       void sortMaxUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true);
+       void sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
+       void sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
+       void sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
+       void sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
 
 public:
-       btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, int maxHandles = 16384);
-       virtual ~btAxisSweep3();
 
-       virtual void    refreshOverlappingPairs();
+       btAxisSweep3Internal(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache=0);
+
+       virtual ~btAxisSweep3Internal();
+
+
+       virtual void    calculateOverlappingPairs(btDispatcher* dispatcher);
        
-       BP_FP_INT_TYPE addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask);
-       void removeHandle(BP_FP_INT_TYPE handle);
-       void updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax);
-       inline Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;}
+       BP_FP_INT_TYPE addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher);
+       void removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher);
+       void updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax,btDispatcher* dispatcher);
+       SIMD_FORCE_INLINE Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;}
 
        void    processAllOverlappingPairs(btOverlapCallback* callback);
 
        //Broadphase Interface
-       virtual btBroadphaseProxy*      createProxy(  const btVector3& min,  const btVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask);
-       virtual void    destroyProxy(btBroadphaseProxy* proxy);
-       virtual void    setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax);
-       bool testOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
+       virtual btBroadphaseProxy*      createProxy(  const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher);
+       virtual void    destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
+       virtual void    setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
+       
+       bool    testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
+
+       btOverlappingPairCache* getOverlappingPairCache()
+       {
+               return m_pairCache;
+       }
+       const btOverlappingPairCache*   getOverlappingPairCache() const
+       {
+               return m_pairCache;
+       }
+
+       void    setOverlappingPairUserCallback(btOverlappingPairCallback* pairCallback)
+       {
+               m_userPairCallback = pairCallback;
+       }
+       const btOverlappingPairCallback*        getOverlappingPairUserCallback() const
+       {
+               return m_userPairCallback;
+       }
+};
+
+////////////////////////////////////////////////////////////////////
+
+
+
+
+#ifdef DEBUG_BROADPHASE
+#include <stdio.h>
+
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3<BP_FP_INT_TYPE>::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;i<numEdges+1;i++)
+       {
+               Edge* pEdge = m_pEdges[axis] + i;
+               Handle* pHandlePrev = getHandle(pEdge->m_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
+
+template <typename BP_FP_INT_TYPE>
+btBroadphaseProxy*     btAxisSweep3Internal<BP_FP_INT_TYPE>::createProxy(  const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher)
+{
+               (void)shapeType;
+               BP_FP_INT_TYPE handleId = addHandle(aabbMin,aabbMax, userPtr,collisionFilterGroup,collisionFilterMask,dispatcher);
+               
+               Handle* handle = getHandle(handleId);
+                               
+               return handle;
+}
+
+
+
+template <typename BP_FP_INT_TYPE>
+void   btAxisSweep3Internal<BP_FP_INT_TYPE>::destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)
+{
+       Handle* handle = static_cast<Handle*>(proxy);
+       removeHandle(handle->m_uniqueId,dispatcher);
+}
+
+template <typename BP_FP_INT_TYPE>
+void   btAxisSweep3Internal<BP_FP_INT_TYPE>::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher)
+{
+       Handle* handle = static_cast<Handle*>(proxy);
+       updateHandle(handle->m_uniqueId,aabbMin,aabbMax,dispatcher);
+
+}
+
+
+
+
+
+template <typename BP_FP_INT_TYPE>
+btAxisSweep3Internal<BP_FP_INT_TYPE>::btAxisSweep3Internal(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel,BP_FP_INT_TYPE maxHandles, btOverlappingPairCache* pairCache )
+:m_bpHandleMask(handleMask),
+m_handleSentinel(handleSentinel),
+m_pairCache(pairCache),
+m_userPairCallback(0),
+m_ownsPairCache(false),
+m_invalidPair(0)
+{
+       if (!m_pairCache)
+       {
+               void* ptr = btAlignedAlloc(sizeof(btOverlappingPairCache),16);
+               m_pairCache = new(ptr) btOverlappingPairCache();
+               m_ownsPairCache = true;
+       }
+
+       //assert(bounds.HasVolume());
+
+       // init bounds
+       m_worldAabbMin = worldAabbMin;
+       m_worldAabbMax = worldAabbMax;
+
+       btVector3 aabbSize = m_worldAabbMax - m_worldAabbMin;
+
+       BP_FP_INT_TYPE  maxInt = m_handleSentinel;
+
+       m_quantize = btVector3(btScalar(maxInt),btScalar(maxInt),btScalar(maxInt)) / aabbSize;
+
+       // allocate handles buffer and put all handles on free list
+       void* ptr = btAlignedAlloc(sizeof(Handle)*maxHandles,16);
+       m_pHandles = new(ptr) Handle[maxHandles];
+       m_maxHandles = maxHandles;
+       m_numHandles = 0;
+
+       // handle 0 is reserved as the null index, and is also used as the sentinel
+       m_firstFreeHandle = 1;
+       {
+               for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < maxHandles; i++)
+                       m_pHandles[i].SetNextFree(i + 1);
+               m_pHandles[maxHandles - 1].SetNextFree(0);
+       }
+
+       {
+               // allocate edge buffers
+               for (int i = 0; i < 3; i++)
+               {
+                       void* ptr = btAlignedAlloc(sizeof(Edge)*maxHandles*2,16);
+                       m_pEdges[i] = new(ptr) Edge[maxHandles * 2];
+               }
+       }
+       //removed overlap management
+
+       // make boundary sentinels
+       
+       m_pHandles[0].m_clientObject = 0;
+
+       for (int axis = 0; axis < 3; axis++)
+       {
+               m_pHandles[0].m_minEdges[axis] = 0;
+               m_pHandles[0].m_maxEdges[axis] = 1;
+
+               m_pEdges[axis][0].m_pos = 0;
+               m_pEdges[axis][0].m_handle = 0;
+               m_pEdges[axis][1].m_pos = m_handleSentinel;
+               m_pEdges[axis][1].m_handle = 0;
+#ifdef DEBUG_BROADPHASE
+               debugPrintAxis(axis);
+#endif //DEBUG_BROADPHASE
+
+       }
+
+}
+
+template <typename BP_FP_INT_TYPE>
+btAxisSweep3Internal<BP_FP_INT_TYPE>::~btAxisSweep3Internal()
+{
+       
+       for (int i = 2; i >= 0; i--)
+       {
+               btAlignedFree(m_pEdges[i]);
+       }
+       btAlignedFree(m_pHandles);
+
+       if (m_ownsPairCache)
+       {
+               m_pairCache->~btOverlappingPairCache();
+               btAlignedFree(m_pairCache);
+       }
+}
+
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const
+{
+       btPoint3 clampedPoint(point);
+       
+
+
+       clampedPoint.setMax(m_worldAabbMin);
+       clampedPoint.setMin(m_worldAabbMax);
+
+       btVector3 v = (clampedPoint - m_worldAabbMin) * m_quantize;
+       out[0] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getX() & m_bpHandleMask) | isMax);
+       out[1] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getY() & m_bpHandleMask) | isMax);
+       out[2] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getZ() & m_bpHandleMask) | isMax);
+       
+}
+
+
+template <typename BP_FP_INT_TYPE>
+BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::allocHandle()
+{
+       assert(m_firstFreeHandle);
+
+       BP_FP_INT_TYPE handle = m_firstFreeHandle;
+       m_firstFreeHandle = getHandle(handle)->GetNextFree();
+       m_numHandles++;
+
+       return handle;
+}
+
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::freeHandle(BP_FP_INT_TYPE handle)
+{
+       assert(handle > 0 && handle < m_maxHandles);
+
+       getHandle(handle)->SetNextFree(m_firstFreeHandle);
+       m_firstFreeHandle = handle;
+
+       m_numHandles--;
+}
+
+
+template <typename BP_FP_INT_TYPE>
+BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher)
+{
+       // quantize the bounds
+       BP_FP_INT_TYPE min[3], max[3];
+       quantize(min, aabbMin, 0);
+       quantize(max, aabbMax, 1);
+
+       // allocate a handle
+       BP_FP_INT_TYPE handle = allocHandle();
+       
+
+       Handle* pHandle = getHandle(handle);
+       
+       pHandle->m_uniqueId = handle;
+       //pHandle->m_pOverlaps = 0;
+       pHandle->m_clientObject = pOwner;
+       pHandle->m_collisionFilterGroup = collisionFilterGroup;
+       pHandle->m_collisionFilterMask = collisionFilterMask;
+
+       // 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];
+
+               m_pEdges[axis][limit - 1].m_pos = min[axis];
+               m_pEdges[axis][limit - 1].m_handle = handle;
+
+               m_pEdges[axis][limit].m_pos = max[axis];
+               m_pEdges[axis][limit].m_handle = handle;
+
+               pHandle->m_minEdges[axis] = limit - 1;
+               pHandle->m_maxEdges[axis] = limit;
+       }
+
+       // now sort the new edges to their correct position
+       sortMinDown(0, pHandle->m_minEdges[0], dispatcher,false);
+       sortMaxDown(0, pHandle->m_maxEdges[0], dispatcher,false);
+       sortMinDown(1, pHandle->m_minEdges[1], dispatcher,false);
+       sortMaxDown(1, pHandle->m_maxEdges[1], dispatcher,false);
+       sortMinDown(2, pHandle->m_minEdges[2], dispatcher,true);
+       sortMaxDown(2, pHandle->m_maxEdges[2], dispatcher,true);
+
+
+       return handle;
+}
+
+
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher)
+{
+
+       Handle* pHandle = getHandle(handle);
+
+       //explicitly remove the pairs containing the proxy
+       //we could do it also in the sortMinUp (passing true)
+       //todo: compare performance
+       m_pairCache->removeOverlappingPairsContainingProxy(pHandle,dispatcher);
+
+
+       // compute current limit of edge arrays
+       int limit = m_numHandles * 2;
+       
+       int axis;
+
+       for (axis = 0;axis<3;axis++)
+       {
+               m_pHandles[0].m_maxEdges[axis] -= 2;
+       }
+
+       // remove the edges by sorting them up to the end of the list
+       for ( axis = 0; axis < 3; axis++)
+       {
+               Edge* pEdges = m_pEdges[axis];
+               BP_FP_INT_TYPE max = pHandle->m_maxEdges[axis];
+               pEdges[max].m_pos = m_handleSentinel;
+
+               sortMaxUp(axis,max,dispatcher,false);
+
+
+               BP_FP_INT_TYPE i = pHandle->m_minEdges[axis];
+               pEdges[i].m_pos = m_handleSentinel;
+
+
+               sortMinUp(axis,i,dispatcher,false);
+
+               pEdges[limit-1].m_handle = 0;
+               pEdges[limit-1].m_pos = m_handleSentinel;
+               
+#ifdef DEBUG_BROADPHASE
+                       debugPrintAxis(axis,false);
+#endif //DEBUG_BROADPHASE
+
+
+       }
+
+
+       // free the handle
+       freeHandle(handle);
+
+       
+}
+
+extern int gOverlappingPairs;
+#include <stdio.h>
+
+template <typename BP_FP_INT_TYPE>
+void   btAxisSweep3Internal<BP_FP_INT_TYPE>::calculateOverlappingPairs(btDispatcher* dispatcher)
+{
+#ifdef USE_LAZY_REMOVAL
+
+       if (m_ownsPairCache)
+       {
+       
+               btBroadphasePairArray&  overlappingPairArray = m_pairCache->getOverlappingPairArray();
+
+               //perform a sort, to find duplicates and to sort 'invalid' pairs to the end
+               overlappingPairArray.heapSort(btBroadphasePairSortPredicate());
+
+               overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
+               m_invalidPair = 0;
+
+               
+               int i;
+
+               btBroadphasePair previousPair;
+               previousPair.m_pProxy0 = 0;
+               previousPair.m_pProxy1 = 0;
+               previousPair.m_algorithm = 0;
+               
+               
+               for (i=0;i<overlappingPairArray.size();i++)
+               {
+               
+                       btBroadphasePair& pair = overlappingPairArray[i];
+
+                       bool isDuplicate = (pair == previousPair);
+
+                       previousPair = pair;
+
+                       bool needsRemoval = false;
+
+                       if (!isDuplicate)
+                       {
+                               bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1);
+
+                               if (hasOverlap)
+                               {
+                                       needsRemoval = false;//callback->processOverlap(pair);
+                               } else
+                               {
+                                       needsRemoval = true;
+                               }
+                       } else
+                       {
+                               //remove duplicate
+                               needsRemoval = true;
+                               //should have no algorithm
+                               btAssert(!pair.m_algorithm);
+                       }
+                       
+                       if (needsRemoval)
+                       {
+                               m_pairCache->cleanOverlappingPair(pair,dispatcher);
+
+               //              m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
+               //              m_overlappingPairArray.pop_back();
+                               pair.m_pProxy0 = 0;
+                               pair.m_pProxy1 = 0;
+                               m_invalidPair++;
+                               gOverlappingPairs--;
+                       } 
+                       
+               }
+
+       ///if you don't like to skip the invalid pairs in the array, execute following code:
+       #define CLEAN_INVALID_PAIRS 1
+       #ifdef CLEAN_INVALID_PAIRS
+
+               //perform a sort, to sort 'invalid' pairs to the end
+               overlappingPairArray.heapSort(btBroadphasePairSortPredicate());
+
+               overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
+               m_invalidPair = 0;
+       #endif//CLEAN_INVALID_PAIRS
+               
+               //printf("overlappingPairArray.size()=%d\n",overlappingPairArray.size());
+       }
+#endif //USE_LAZY_REMOVAL
+
+
+       
+
+}
+
+
+template <typename BP_FP_INT_TYPE>
+bool btAxisSweep3Internal<BP_FP_INT_TYPE>::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
+{
+       const Handle* pHandleA = static_cast<Handle*>(proxy0);
+       const Handle* pHandleB = static_cast<Handle*>(proxy1);
+       
+       //optimization 1: check the array index (memory address), instead of the m_pos
+
+       for (int axis = 0; axis < 3; axis++)
+       { 
+               if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] || 
+                       pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis]) 
+               { 
+                       return false; 
+               } 
+       } 
+       return true;
+}
+
+template <typename BP_FP_INT_TYPE>
+bool btAxisSweep3Internal<BP_FP_INT_TYPE>::testOverlap(int ignoreAxis,const Handle* pHandleA, const Handle* pHandleB)
+{
+       //optimization 1: check the array index (memory address), instead of the m_pos
+
+       for (int axis = 0; axis < 3; axis++)
+       { 
+               if (axis != ignoreAxis)
+               {
+                       if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] || 
+                               pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis]) 
+                       { 
+                               return false; 
+                       } 
+               }
+       } 
+
+       //optimization 2: only 2 axis need to be tested (conflicts with 'delayed removal' optimization)
+
+       /*for (int axis = 0; axis < 3; axis++)
+       {
+               if (m_pEdges[axis][pHandleA->m_maxEdges[axis]].m_pos < m_pEdges[axis][pHandleB->m_minEdges[axis]].m_pos ||
+                       m_pEdges[axis][pHandleB->m_maxEdges[axis]].m_pos < m_pEdges[axis][pHandleA->m_minEdges[axis]].m_pos)
+               {
+                       return false;
+               }
+       }
+       */
+
+       return true;
+}
+
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax,btDispatcher* dispatcher)
+{
+//     assert(bounds.IsFinite());
+       //assert(bounds.HasVolume());
+
+       Handle* pHandle = getHandle(handle);
+
+       // quantize the new bounds
+       BP_FP_INT_TYPE min[3], max[3];
+       quantize(min, aabbMin, 0);
+       quantize(max, aabbMax, 1);
+
+       // update changed edges
+       for (int axis = 0; axis < 3; axis++)
+       {
+               BP_FP_INT_TYPE emin = pHandle->m_minEdges[axis];
+               BP_FP_INT_TYPE emax = pHandle->m_maxEdges[axis];
+
+               int dmin = (int)min[axis] - (int)m_pEdges[axis][emin].m_pos;
+               int dmax = (int)max[axis] - (int)m_pEdges[axis][emax].m_pos;
+
+               m_pEdges[axis][emin].m_pos = min[axis];
+               m_pEdges[axis][emax].m_pos = max[axis];
+
+               // expand (only adds overlaps)
+               if (dmin < 0)
+                       sortMinDown(axis, emin,dispatcher,true);
+
+               if (dmax > 0)
+                       sortMaxUp(axis, emax,dispatcher,true);
+
+               // shrink (only removes overlaps)
+               if (dmin > 0)
+                       sortMinUp(axis, emin,dispatcher,true);
+
+               if (dmax < 0)
+                       sortMaxDown(axis, emax,dispatcher,true);
+
+#ifdef DEBUG_BROADPHASE
+       debugPrintAxis(axis);
+#endif //DEBUG_BROADPHASE
+       }
+
+       
+}
+
+
+
+
+// sorting a min edge downwards can only ever *add* overlaps
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps)
+{
+
+       Edge* pEdge = m_pEdges[axis] + edge;
+       Edge* pPrev = pEdge - 1;
+       Handle* pHandleEdge = getHandle(pEdge->m_handle);
+
+       while (pEdge->m_pos < pPrev->m_pos)
+       {
+               Handle* pHandlePrev = getHandle(pPrev->m_handle);
+
+               if (pPrev->IsMax())
+               {
+                       // if previous edge is a maximum check the bounds and add an overlap if necessary
+                       if (updateOverlaps && testOverlap(axis,pHandleEdge, pHandlePrev))
+                       {
+                               m_pairCache->addOverlappingPair(pHandleEdge,pHandlePrev);
+                               if (m_userPairCallback)
+                                       m_userPairCallback->addOverlappingPair(pHandleEdge,pHandlePrev);
+
+                               //AddOverlap(pEdge->m_handle, pPrev->m_handle);
+
+                       }
+
+                       // update edge reference in other handle
+                       pHandlePrev->m_maxEdges[axis]++;
+               }
+               else
+                       pHandlePrev->m_minEdges[axis]++;
+
+               pHandleEdge->m_minEdges[axis]--;
+
+               // swap the edges
+               Edge swap = *pEdge;
+               *pEdge = *pPrev;
+               *pPrev = swap;
+
+               // decrement
+               pEdge--;
+               pPrev--;
+       }
+
+#ifdef DEBUG_BROADPHASE
+       debugPrintAxis(axis);
+#endif //DEBUG_BROADPHASE
+
+}
+
+// sorting a min edge upwards can only ever *remove* overlaps
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps)
+{
+       Edge* pEdge = m_pEdges[axis] + edge;
+       Edge* pNext = pEdge + 1;
+       Handle* pHandleEdge = getHandle(pEdge->m_handle);
+
+       while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos))
+       {
+               Handle* pHandleNext = getHandle(pNext->m_handle);
+
+               if (pNext->IsMax())
+               {
+#ifndef USE_LAZY_REMOVAL
+                       // if next edge is maximum remove any overlap between the two handles
+                       if (updateOverlaps)
+                       {
+                               Handle* handle0 = getHandle(pEdge->m_handle);
+                               Handle* handle1 = getHandle(pNext->m_handle);
+
+                               m_pairCache->removeOverlappingPair(handle0,handle1,dispatcher); 
+                               if (m_userPairCallback)
+                                       m_userPairCallback->removeOverlappingPair(handle0,handle1);
+                               
+                       }
+#endif //USE_LAZY_REMOVAL
+
+                       // update edge reference in other handle
+                       pHandleNext->m_maxEdges[axis]--;
+               }
+               else
+                       pHandleNext->m_minEdges[axis]--;
+
+               pHandleEdge->m_minEdges[axis]++;
+
+               // swap the edges
+               Edge swap = *pEdge;
+               *pEdge = *pNext;
+               *pNext = swap;
+
+               // increment
+               pEdge++;
+               pNext++;
+       }
+
+
+}
+
+// sorting a max edge downwards can only ever *remove* overlaps
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps)
+{
+
+       Edge* pEdge = m_pEdges[axis] + edge;
+       Edge* pPrev = pEdge - 1;
+       Handle* pHandleEdge = getHandle(pEdge->m_handle);
+
+       while (pEdge->m_pos < pPrev->m_pos)
+       {
+               Handle* pHandlePrev = getHandle(pPrev->m_handle);
+
+               if (!pPrev->IsMax())
+               {
+                       // if previous edge was a minimum remove any overlap between the two handles
+                       if (updateOverlaps)
+                       {
+                               //this is done during the overlappingpairarray iteration/narrowphase collision
+#ifndef USE_LAZY_REMOVAL
+                               Handle* handle0 = getHandle(pEdge->m_handle);
+                               Handle* handle1 = getHandle(pPrev->m_handle);
+                               m_pairCache->removeOverlappingPair(handle0,handle1,dispatcher);
+                               if (m_userPairCallback)
+                                       m_userPairCallback->removeOverlappingPair(handle0,handle1);
+                       
+#endif //USE_LAZY_REMOVAL              
+
+                       }
+
+                       // update edge reference in other handle
+                       pHandlePrev->m_minEdges[axis]++;;
+               }
+               else
+                       pHandlePrev->m_maxEdges[axis]++;
+
+               pHandleEdge->m_maxEdges[axis]--;
+
+               // swap the edges
+               Edge swap = *pEdge;
+               *pEdge = *pPrev;
+               *pPrev = swap;
+
+               // decrement
+               pEdge--;
+               pPrev--;
+       }
+
+       
+#ifdef DEBUG_BROADPHASE
+       debugPrintAxis(axis);
+#endif //DEBUG_BROADPHASE
+
+}
+
+// sorting a max edge upwards can only ever *add* overlaps
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps)
+{
+       Edge* pEdge = m_pEdges[axis] + edge;
+       Edge* pNext = pEdge + 1;
+       Handle* pHandleEdge = getHandle(pEdge->m_handle);
+
+       while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos))
+       {
+               Handle* pHandleNext = getHandle(pNext->m_handle);
+
+               if (!pNext->IsMax())
+               {
+                       // if next edge is a minimum check the bounds and add an overlap if necessary
+                       if (updateOverlaps && testOverlap(axis, pHandleEdge, pHandleNext))
+                       {
+                               Handle* handle0 = getHandle(pEdge->m_handle);
+                               Handle* handle1 = getHandle(pNext->m_handle);
+                               m_pairCache->addOverlappingPair(handle0,handle1);
+                               if (m_userPairCallback)
+                                       m_userPairCallback->addOverlappingPair(handle0,handle1);
+                       }
+
+                       // update edge reference in other handle
+                       pHandleNext->m_minEdges[axis]--;
+               }
+               else
+                       pHandleNext->m_maxEdges[axis]--;
+
+               pHandleEdge->m_maxEdges[axis]++;
+
+               // swap the edges
+               Edge swap = *pEdge;
+               *pEdge = *pNext;
+               *pNext = swap;
+
+               // increment
+               pEdge++;
+               pNext++;
+       }
+       
+}
+
+
+
+////////////////////////////////////////////////////////////////////
+
+
+/// 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 16 bit integer coordinates instead of floats.
+/// For large worlds and many objects, use bt32BitAxisSweep3 instead. bt32BitAxisSweep3 has higher precision and allows more then 16384 objects at the cost of more memory and bit of performance.
+class btAxisSweep3 : public btAxisSweep3Internal<unsigned short int>
+{
+public:
+
+       btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0);
+
+};
+
+/// bt32BitAxisSweep3 allows higher precision quantization and more objects compared to the btAxisSweep3 sweep and prune.
+/// This comes at the cost of more memory per handle, and a bit slower performance.
+/// It uses arrays rather then lists for storage of the 3 axis.
+class bt32BitAxisSweep3 : public btAxisSweep3Internal<unsigned int>
+{
+public:
+
+       bt32BitAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0);
 
 };
 
index b6ace03c07af5c451e2fdb95d9af8d96b4508453..97ba20743d25c11073bae32698da5be0190b1db1 100644 (file)
@@ -20,8 +20,10 @@ subject to the following restrictions:
 
 struct btDispatcherInfo;
 class btDispatcher;
-struct btBroadphaseProxy;
-#include "../../LinearMath/btVector3.h"
+#include "btBroadphaseProxy.h"
+class btOverlappingPairCache;
+
+#include "LinearMath/btVector3.h"
 
 ///BroadphaseInterface for aabb-overlapping object pairs
 class btBroadphaseInterface
@@ -29,11 +31,15 @@ class btBroadphaseInterface
 public:
        virtual ~btBroadphaseInterface() {}
 
-       virtual btBroadphaseProxy*      createProxy(  const btVector3& min,  const btVector3& max,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask) =0;
-       virtual void    destroyProxy(btBroadphaseProxy* proxy)=0;
-       virtual void    setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax)=0;
-       virtual void    cleanProxyFromPairs(btBroadphaseProxy* proxy)=0;
+       virtual btBroadphaseProxy*      createProxy(  const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher) =0;
+       virtual void    destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)=0;
+       virtual void    setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)=0;
        
+       ///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb
+       virtual void    calculateOverlappingPairs(btDispatcher* dispatcher)=0;
+
+       virtual btOverlappingPairCache* getOverlappingPairCache()=0;
+       virtual const btOverlappingPairCache*   getOverlappingPairCache() const =0;
 
 };
 
index 40d9748ffa91e941ad6212172a60d27001bb596f..f0a462cce02a8df4cbaa85cc574f49e567e0976f 100644 (file)
@@ -16,7 +16,8 @@ subject to the following restrictions:
 #ifndef BROADPHASE_PROXY_H
 #define BROADPHASE_PROXY_H
 
-#include "../../LinearMath/btScalar.h" //for SIMD_FORCE_INLINE
+#include "LinearMath/btScalar.h" //for SIMD_FORCE_INLINE
+#include "LinearMath/btAlignedAllocator.h"
 
 
 /// btDispatcher uses these types
@@ -38,6 +39,7 @@ IMPLICIT_CONVEX_SHAPES_START_HERE,
        CONE_SHAPE_PROXYTYPE,
        CONVEX_SHAPE_PROXYTYPE,
        CYLINDER_SHAPE_PROXYTYPE,
+       UNIFORM_SCALING_SHAPE_PROXYTYPE,
        MINKOWSKI_SUM_SHAPE_PROXYTYPE,
        MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE,
 //concave shapes
@@ -62,8 +64,10 @@ CONCAVE_SHAPES_END_HERE,
 
 
 ///btBroadphaseProxy
-struct btBroadphaseProxy
+ATTRIBUTE_ALIGNED16(struct) btBroadphaseProxy
 {
+
+BT_DECLARE_ALIGNED_ALLOCATOR();
        
        ///optional filtering to cull potential collisions
        enum CollisionFilterGroups
@@ -78,8 +82,27 @@ struct btBroadphaseProxy
 
        //Usually the client btCollisionObject or Rigidbody class
        void*   m_clientObject;
-       short int m_collisionFilterGroup;
-       short int m_collisionFilterMask;
+
+       ///in the case of btMultiSapBroadphase, we store the collifionFilterGroup/Mask in the m_multiSapParentProxy
+       union
+       {
+               struct
+               {
+                       short int m_collisionFilterGroup;
+                       short int m_collisionFilterMask;
+               };
+
+               void*   m_multiSapParentProxy;
+
+       };
+
+       int                     m_uniqueId;//m_uniqueId is introduced for paircache. could get rid of this, by calculating the address offset etc.
+       int m_unusedPadding; //making the structure 16 bytes, better for alignment etc.
+
+       SIMD_FORCE_INLINE int getUid()
+       {
+               return m_uniqueId;//(int)this;
+       }
 
        //used for memory pools
        btBroadphaseProxy() :m_clientObject(0){}
@@ -91,26 +114,28 @@ struct btBroadphaseProxy
        {
        }
 
-       static inline bool isPolyhedral(int proxyType)
+       
+
+       static SIMD_FORCE_INLINE bool isPolyhedral(int proxyType)
        {
                return (proxyType  < IMPLICIT_CONVEX_SHAPES_START_HERE);
        }
 
-       static inline bool      isConvex(int proxyType)
+       static SIMD_FORCE_INLINE bool   isConvex(int proxyType)
        {
                return (proxyType < CONCAVE_SHAPES_START_HERE);
        }
 
-       static inline bool      isConcave(int proxyType)
+       static SIMD_FORCE_INLINE bool   isConcave(int proxyType)
        {
                return ((proxyType > CONCAVE_SHAPES_START_HERE) &&
                        (proxyType < CONCAVE_SHAPES_END_HERE));
        }
-       static inline bool      isCompound(int proxyType)
+       static SIMD_FORCE_INLINE bool   isCompound(int proxyType)
        {
                return (proxyType == COMPOUND_SHAPE_PROXYTYPE);
        }
-       static inline bool isInfinite(int proxyType)
+       static SIMD_FORCE_INLINE bool isInfinite(int proxyType)
        {
                return (proxyType == STATIC_PLANE_PROXYTYPE);
        }
@@ -125,7 +150,7 @@ struct btBroadphaseProxy;
 
 
 /// contains a pair of aabb-overlapping objects
-struct btBroadphasePair
+ATTRIBUTE_ALIGNED16(struct) btBroadphasePair
 {
        btBroadphasePair ()
                :
@@ -136,6 +161,8 @@ struct btBroadphasePair
        {
        }
 
+BT_DECLARE_ALIGNED_ALLOCATOR();
+
        btBroadphasePair(const btBroadphasePair& other)
                :               m_pProxy0(other.m_pProxy0),
                                m_pProxy1(other.m_pProxy1),
@@ -181,6 +208,7 @@ SIMD_FORCE_INLINE bool operator<(const btBroadphasePair& a, const btBroadphasePa
 */
 
 
+
 class btBroadphasePairSortPredicate
 {
        public:
index 2ad0c86d8a2d7551e6ac25353934354d85240925..c95d1be0f2ce667f123d3b245ab57ca55591ffb8 100644 (file)
@@ -18,6 +18,6 @@ subject to the following restrictions:
 
 btCollisionAlgorithm::btCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
 {
-       m_dispatcher = ci.m_dispatcher;
+       m_dispatcher = ci.m_dispatcher1;
 }
 
index 55cec386a7bf19d41b9e7214e56982b2747202d8..610eab4ce5e40c8c24ac2ab14aabd0241cbbf768 100644 (file)
@@ -16,7 +16,7 @@ subject to the following restrictions:
 #ifndef COLLISION_ALGORITHM_H
 #define COLLISION_ALGORITHM_H
 
-#include "../../LinearMath/btScalar.h"
+#include "LinearMath/btScalar.h"
 
 struct btBroadphaseProxy;
 class btDispatcher;
@@ -29,17 +29,17 @@ class       btPersistentManifold;
 struct btCollisionAlgorithmConstructionInfo
 {
        btCollisionAlgorithmConstructionInfo()
-               :m_dispatcher(0),
+               :m_dispatcher1(0),
                m_manifold(0)
        {
        }
        btCollisionAlgorithmConstructionInfo(btDispatcher* dispatcher,int temp)
-               :m_dispatcher(dispatcher)
+               :m_dispatcher1(dispatcher)
        {
                (void)temp;
        }
 
-       btDispatcher*   m_dispatcher;
+       btDispatcher*   m_dispatcher1;
        btPersistentManifold*   m_manifold;
 
        int     getDispatcherId();
index 3d958cc8fef19f75310c3cd9a8c3b3ce51f0ab2c..daea11f77886a2afd380f97f1074e5fb6143d413 100644 (file)
@@ -16,7 +16,7 @@ subject to the following restrictions:
 #ifndef _DISPATCHER_H
 #define _DISPATCHER_H
 
-#include "../../LinearMath/btScalar.h"
+#include "LinearMath/btScalar.h"
 
 class btCollisionAlgorithm;
 struct btBroadphaseProxy;
@@ -81,12 +81,18 @@ public:
 
        virtual bool    needsResponse(btCollisionObject* body0,btCollisionObject* body1)=0;
 
-       virtual void    dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo)=0;
+       virtual void    dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher)=0;
 
        virtual int getNumManifolds() const = 0;
 
        virtual btPersistentManifold* getManifoldByIndexInternal(int index) = 0;
 
+       virtual btPersistentManifold**  getInternalManifoldPointer() = 0;
+
+       virtual void* allocateCollisionAlgorithm(int size) = 0;
+
+       virtual void freeCollisionAlgorithm(void* ptr) = 0;
+
 };
 
 
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp
new file mode 100644 (file)
index 0000000..41406ff
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "btMultiSapBroadphase.h"
+
+#include "btSimpleBroadphase.h"
+#include "LinearMath/btAabbUtil2.h"
+
+///    btSapBroadphaseArray    m_sapBroadphases;
+
+///    btOverlappingPairCache* m_overlappingPairs;
+extern int gOverlappingPairs;
+
+btMultiSapBroadphase::btMultiSapBroadphase(int maxProxies,btOverlappingPairCache* pairCache)
+:m_overlappingPairs(pairCache),
+m_ownsPairCache(false),
+m_invalidPair(0)
+{
+       if (!m_overlappingPairs)
+       {
+               m_ownsPairCache = true;
+               void* mem = btAlignedAlloc(sizeof(btOverlappingPairCache),16);
+               m_overlappingPairs = new (mem)btOverlappingPairCache();
+       }
+
+       struct btMultiSapOverlapFilterCallback : public btOverlapFilterCallback
+       {
+               virtual ~btMultiSapOverlapFilterCallback()
+               {}
+               // return true when pairs need collision
+               virtual bool    needBroadphaseCollision(btBroadphaseProxy* childProxy0,btBroadphaseProxy* childProxy1) const
+               {
+                       btMultiSapBroadphase::btMultiSapProxy* multiSapProxy0 = (btMultiSapBroadphase::btMultiSapProxy*)childProxy0->m_multiSapParentProxy;
+                       btMultiSapBroadphase::btMultiSapProxy* multiSapProxy1 = (btMultiSapBroadphase::btMultiSapProxy*)childProxy1->m_multiSapParentProxy;
+                       
+                       bool collides = (multiSapProxy0->m_collisionFilterGroup & multiSapProxy1->m_collisionFilterMask) != 0;
+                       collides = collides && (multiSapProxy1->m_collisionFilterGroup & multiSapProxy0->m_collisionFilterMask);
+       
+                       return collides;
+               }
+       };
+
+       void* mem = btAlignedAlloc(sizeof(btMultiSapOverlapFilterCallback),16);
+       m_filterCallback = new (mem)btMultiSapOverlapFilterCallback();
+
+       m_overlappingPairs->setOverlapFilterCallback(m_filterCallback);
+       mem = btAlignedAlloc(sizeof(btSimpleBroadphase),16);
+       m_simpleBroadphase = new (mem) btSimpleBroadphase(maxProxies,m_overlappingPairs);
+}
+
+btMultiSapBroadphase::~btMultiSapBroadphase()
+{
+       if (m_ownsPairCache)
+       {
+               btAlignedFree(m_overlappingPairs);
+       }
+}
+
+btBroadphaseProxy*     btMultiSapBroadphase::createProxy(  const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher)
+{
+       void* mem = btAlignedAlloc(sizeof(btMultiSapProxy),16);
+       btMultiSapProxy* proxy = new (mem)btMultiSapProxy(aabbMin,  aabbMax,shapeType,userPtr, collisionFilterGroup,collisionFilterMask);
+       m_multiSapProxies.push_back(proxy);
+
+       ///we don't pass the userPtr but our multisap proxy. We need to patch this, before processing an actual collision
+       ///this is needed to be able to calculate the aabb overlap
+       btBroadphaseProxy* simpleProxy = m_simpleBroadphase->createProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask, dispatcher);
+       simpleProxy->m_multiSapParentProxy = proxy;
+
+       mem = btAlignedAlloc(sizeof(btChildProxy),16);
+       btChildProxy* childProxyRef = new btChildProxy();
+       childProxyRef->m_proxy = simpleProxy;
+       childProxyRef->m_childBroadphase = m_simpleBroadphase;
+       proxy->m_childProxies.push_back(childProxyRef);
+
+       ///this should deal with inserting/removal into child broadphases
+       setAabb(proxy,aabbMin,aabbMax,dispatcher);
+       return proxy;
+}
+
+void   btMultiSapBroadphase::destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)
+{
+       ///not yet
+       btAssert(0);
+
+}
+void   btMultiSapBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)
+{
+       btMultiSapProxy* multiProxy = static_cast<btMultiSapProxy*>(proxy);
+       multiProxy->m_aabbMin = aabbMin;
+       multiProxy->m_aabbMax = aabbMax;
+
+       for (int i=0;i<multiProxy->m_childProxies.size();i++)
+       {
+               btChildProxy* childProxyRef = multiProxy->m_childProxies[i];
+               childProxyRef->m_childBroadphase->setAabb(childProxyRef->m_proxy,aabbMin,aabbMax,dispatcher);
+       }
+
+}
+       
+       ///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb
+void   btMultiSapBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
+{
+       m_simpleBroadphase->calculateOverlappingPairs(dispatcher);
+
+#ifndef USE_HASH_PAIRCACHE
+
+       btBroadphasePairArray&  overlappingPairArray = m_overlappingPairs->getOverlappingPairArray();
+       
+       //perform a sort, to find duplicates and to sort 'invalid' pairs to the end
+       overlappingPairArray.heapSort(btBroadphasePairSortPredicate());
+
+       overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
+       m_invalidPair = 0;
+
+
+       btBroadphasePair previousPair;
+       previousPair.m_pProxy0 = 0;
+       previousPair.m_pProxy1 = 0;
+       previousPair.m_algorithm = 0;
+       
+       int i;
+
+       for (i=0;i<overlappingPairArray.size();i++)
+       {
+       
+               btBroadphasePair& pair = overlappingPairArray[i];
+
+               bool isDuplicate = (pair == previousPair);
+
+               previousPair = pair;
+
+               bool needsRemoval = false;
+
+               if (!isDuplicate)
+               {
+                       bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1);
+
+                       if (hasOverlap)
+                       {
+                               needsRemoval = false;//callback->processOverlap(pair);
+                       } else
+                       {
+                               needsRemoval = true;
+                       }
+               } else
+               {
+                       //remove duplicate
+                       needsRemoval = true;
+                       //should have no algorithm
+                       btAssert(!pair.m_algorithm);
+               }
+               
+               if (needsRemoval)
+               {
+                       m_overlappingPairs->cleanOverlappingPair(pair,dispatcher);
+
+       //              m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
+       //              m_overlappingPairArray.pop_back();
+                       pair.m_pProxy0 = 0;
+                       pair.m_pProxy1 = 0;
+                       m_invalidPair++;
+                       gOverlappingPairs--;
+               } 
+               
+       }
+
+///if you don't like to skip the invalid pairs in the array, execute following code:
+#define CLEAN_INVALID_PAIRS 1
+#ifdef CLEAN_INVALID_PAIRS
+
+       //perform a sort, to sort 'invalid' pairs to the end
+       overlappingPairArray.heapSort(btBroadphasePairSortPredicate());
+
+       overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
+       m_invalidPair = 0;
+#endif//CLEAN_INVALID_PAIRS
+
+#endif //USE_HASH_PAIRCACHE
+
+}
+
+
+bool   btMultiSapBroadphase::testAabbOverlap(btBroadphaseProxy* childProxy0,btBroadphaseProxy* childProxy1)
+{
+               btMultiSapProxy* multiSapProxy0 = (btMultiSapProxy*)childProxy0->m_multiSapParentProxy;
+               btMultiSapProxy* multiSapProxy1 = (btMultiSapProxy*)childProxy1->m_multiSapParentProxy;
+
+               return  TestAabbAgainstAabb2(multiSapProxy0->m_aabbMin,multiSapProxy0->m_aabbMax,
+                       multiSapProxy1->m_aabbMin,multiSapProxy1->m_aabbMax);
+               
+}
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h
new file mode 100644 (file)
index 0000000..1ee609b
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef BT_MULTI_SAP_BROADPHASE
+#define BT_MULTI_SAP_BROADPHASE
+
+#include "btBroadphaseInterface.h"
+#include "LinearMath/btAlignedObjectArray.h"
+#include "btOverlappingPairCache.h"
+
+class btAxisSweep3;
+class btSimpleBroadphase;
+
+
+typedef btAlignedObjectArray<btAxisSweep3*> btSapBroadphaseArray;
+
+///multi SAP broadphase
+///See http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=328
+///and http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1329
+class btMultiSapBroadphase :public btBroadphaseInterface
+{
+       btSapBroadphaseArray    m_sapBroadphases;
+       
+       btSimpleBroadphase*             m_simpleBroadphase;
+
+       btOverlappingPairCache* m_overlappingPairs;
+
+       bool                                    m_ownsPairCache;
+       
+       btOverlapFilterCallback*        m_filterCallback;
+
+       int                     m_invalidPair;
+
+       struct  btChildProxy
+       {
+               btBroadphaseProxy*              m_proxy;
+               btBroadphaseInterface*  m_childBroadphase;
+       };
+
+public:
+
+       struct  btMultiSapProxy : public btBroadphaseProxy
+       {
+
+               ///array with all the entries that this proxy belongs to
+               btAlignedObjectArray<btChildProxy*> m_childProxies;
+               btVector3       m_aabbMin;
+               btVector3       m_aabbMax;
+
+               int     m_shapeType;
+               void*   m_userPtr;
+               short int       m_collisionFilterGroup;
+               short int       m_collisionFilterMask;
+
+               btMultiSapProxy(const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask)
+                       :m_aabbMin(aabbMin),
+                       m_aabbMax(aabbMax),
+                       m_shapeType(shapeType),
+                       m_userPtr(userPtr),
+                       m_collisionFilterGroup(collisionFilterGroup),
+                       m_collisionFilterMask(collisionFilterMask)
+               {
+
+               }
+
+               
+       };
+
+protected:
+
+       btAlignedObjectArray<btMultiSapProxy*> m_multiSapProxies;
+
+public:
+
+       btMultiSapBroadphase(int maxProxies = 16384,btOverlappingPairCache* pairCache=0);
+
+       btSapBroadphaseArray    getBroadphaseArray()
+       {
+               return m_sapBroadphases;
+       }
+
+       const btSapBroadphaseArray      getBroadphaseArray() const
+       {
+               return m_sapBroadphases;
+       }
+
+       virtual ~btMultiSapBroadphase();
+
+       virtual btBroadphaseProxy*      createProxy(  const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher);
+       virtual void    destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
+       virtual void    setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher);
+       
+       ///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb
+       virtual void    calculateOverlappingPairs(btDispatcher* dispatcher);
+
+       bool    testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
+
+       virtual btOverlappingPairCache* getOverlappingPairCache()
+       {
+               return m_overlappingPairs;
+       }
+       virtual const btOverlappingPairCache*   getOverlappingPairCache() const
+       {
+               return m_overlappingPairs;
+       }
+};
+
+#endif //BT_MULTI_SAP_BROADPHASE
index 60f0a41a9d76ae9f9ffb203e9dc79b3b80814018..e4ef043f06455574360ea7eae70044e02cce9887 100644 (file)
@@ -23,11 +23,19 @@ subject to the following restrictions:
 
 int    gOverlappingPairs = 0;
 
+int gRemovePairs =0;
+int gAddedPairs =0;
+int gFindPairs =0;
+
 btOverlappingPairCache::btOverlappingPairCache():
-m_blockedForChanges(false),
-m_overlapFilterCallback(0)
-//m_NumOverlapBroadphasePair(0)
+       m_overlapFilterCallback(0),
+       m_blockedForChanges(false)
 {
+       int initialAllocatedSize= 2;
+       m_overlappingPairArray.reserve(initialAllocatedSize);
+#ifdef USE_HASH_PAIRCACHE
+       growTables();
+#endif //USE_HASH_PAIRCACHE
 }
 
 
@@ -36,91 +44,33 @@ btOverlappingPairCache::~btOverlappingPairCache()
        //todo/test: show we erase/delete data, or is it automatic
 }
 
-
-void   btOverlappingPairCache::removeOverlappingPair(btBroadphasePair& findPair)
-{
-       
-       int findIndex = m_overlappingPairArray.findLinearSearch(findPair);
-       if (findIndex < m_overlappingPairArray.size())
-       {
-               gOverlappingPairs--;
-               btBroadphasePair& pair = m_overlappingPairArray[findIndex];
-               cleanOverlappingPair(pair);
-               
-               m_overlappingPairArray.swap(findIndex,m_overlappingPairArray.size()-1);
-               m_overlappingPairArray.pop_back();
-       }
-}
-
-
-void   btOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair)
+void   btOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher)
 {
        if (pair.m_algorithm)
        {
                {
-                       delete pair.m_algorithm;;
+                       pair.m_algorithm->~btCollisionAlgorithm();
+                       dispatcher->freeCollisionAlgorithm(pair.m_algorithm);
                        pair.m_algorithm=0;
                }
        }
 }
 
 
-
-
-
-void   btOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
-{
-       //don't add overlap with own
-       assert(proxy0 != proxy1);
-
-       if (!needsBroadphaseCollision(proxy0,proxy1))
-               return;
-
-
-       btBroadphasePair pair(*proxy0,*proxy1);
-       
-       m_overlappingPairArray.push_back(pair);
-       gOverlappingPairs++;
-       
-}
-
-///this findPair becomes really slow. Either sort the list to speedup the query, or
-///use a different solution. It is mainly used for Removing overlapping pairs. Removal could be delayed.
-///we could keep a linked list in each proxy, and store pair in one of the proxies (with lowest memory address)
-///Also we can use a 2D bitmap, which can be useful for a future GPU implementation
- btBroadphasePair*     btOverlappingPairCache::findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
-{
-       if (!needsBroadphaseCollision(proxy0,proxy1))
-               return 0;
-
-       btBroadphasePair tmpPair(*proxy0,*proxy1);
-       int findIndex = m_overlappingPairArray.findLinearSearch(tmpPair);
-
-       if (findIndex < m_overlappingPairArray.size())
-       {
-               //assert(it != m_overlappingPairSet.end());
-                btBroadphasePair* pair = &m_overlappingPairArray[findIndex];
-               return pair;
-       }
-       return 0;
-}
-
-
-
-
-
-void   btOverlappingPairCache::cleanProxyFromPairs(btBroadphaseProxy* proxy)
+void   btOverlappingPairCache::cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher)
 {
 
        class   CleanPairCallback : public btOverlapCallback
        {
                btBroadphaseProxy* m_cleanProxy;
                btOverlappingPairCache* m_pairCache;
+               btDispatcher* m_dispatcher;
 
        public:
-               CleanPairCallback(btBroadphaseProxy* cleanProxy,btOverlappingPairCache* pairCache)
+               CleanPairCallback(btBroadphaseProxy* cleanProxy,btOverlappingPairCache* pairCache,btDispatcher* dispatcher)
                        :m_cleanProxy(cleanProxy),
-                       m_pairCache(pairCache)
+                       m_pairCache(pairCache),
+                       m_dispatcher(dispatcher)
                {
                }
                virtual bool    processOverlap(btBroadphasePair& pair)
@@ -128,22 +78,20 @@ void       btOverlappingPairCache::cleanProxyFromPairs(btBroadphaseProxy* proxy)
                        if ((pair.m_pProxy0 == m_cleanProxy) ||
                                (pair.m_pProxy1 == m_cleanProxy))
                        {
-                               m_pairCache->cleanOverlappingPair(pair);
+                               m_pairCache->cleanOverlappingPair(pair,m_dispatcher);
                        }
                        return false;
                }
                
        };
 
-       CleanPairCallback cleanPairs(proxy,this);
+       CleanPairCallback cleanPairs(proxy,this,dispatcher);
 
-       processAllOverlappingPairs(&cleanPairs);
+       processAllOverlappingPairs(&cleanPairs,dispatcher);
 
 }
 
-
-
-void   btOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy)
+void   btOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)
 {
 
        class   RemovePairCallback : public btOverlapCallback
@@ -166,12 +114,339 @@ void     btOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseP
 
        RemovePairCallback removeCallback(proxy);
 
-       processAllOverlappingPairs(&removeCallback);
+       processAllOverlappingPairs(&removeCallback,dispatcher);
+}
+
+
+#ifdef USE_HASH_PAIRCACHE
+
+
+
+
+
+
+
+btBroadphasePair* btOverlappingPairCache::findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1)
+{
+       gFindPairs++;
+
+       int proxyId1 = proxy0->getUid();
+       int proxyId2 = proxy1->getUid();
+
+       if (proxyId1 > proxyId2) 
+               btSwap(proxyId1, proxyId2);
+
+       int hash = getHash(proxyId1, proxyId2) & (m_overlappingPairArray.capacity()-1);
+
+       int index = m_hashTable[hash];
+       while (index != BT_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false)
+       {
+               index = m_next[index];
+       }
+
+       if (index == BT_NULL_PAIR)
+       {
+               return NULL;
+       }
+
+       btAssert(index < m_overlappingPairArray.size());
+
+       return &m_overlappingPairArray[index];
+}
+
+#include <stdio.h>
+
+void   btOverlappingPairCache::growTables()
+{
+
+       int newCapacity = m_overlappingPairArray.capacity();
+
+       if (m_hashTable.size() < newCapacity)
+       {
+               //grow hashtable and next table
+               int curHashtableSize = m_hashTable.size();
+
+               m_hashTable.resize(newCapacity);
+               m_next.resize(newCapacity);
+
+
+               int i;
+
+               for (i= 0; i < newCapacity; ++i)
+               {
+                       m_hashTable[i] = BT_NULL_PAIR;
+               }
+               for (i = 0; i < newCapacity; ++i)
+               {
+                       m_next[i] = BT_NULL_PAIR;
+               }
+
+               for(i=0;i<curHashtableSize;i++)
+               {
+       
+                       const btBroadphasePair& pair = m_overlappingPairArray[i];
+                       int proxyId1 = pair.m_pProxy0->getUid();
+                       int proxyId2 = pair.m_pProxy1->getUid();
+                       if (proxyId1 > proxyId2) 
+                               btSwap(proxyId1, proxyId2);
+                       int     hashValue = getHash(proxyId1,proxyId2) & (m_overlappingPairArray.capacity()-1); // New hash value with new mask
+                       m_next[i] = m_hashTable[hashValue];
+                       m_hashTable[hashValue] = i;
+               }
+
+
+       }
+}
+
+btBroadphasePair* btOverlappingPairCache::internalAddPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1)
+{
+       int proxyId1 = proxy0->getUid();
+       int proxyId2 = proxy1->getUid();
+
+       if (proxyId1 > proxyId2) 
+               btSwap(proxyId1, proxyId2);
+
+       int hash = getHash(proxyId1, proxyId2) & (m_overlappingPairArray.capacity()-1);
+
+       
+
+       btBroadphasePair* pair = internalFindPair(proxy0, proxy1, hash);
+       if (pair != NULL)
+       {
+               return pair;
+       }
+
+       int count = m_overlappingPairArray.size();
+       int oldCapacity = m_overlappingPairArray.capacity();
+       void* mem = &m_overlappingPairArray.expand();
+       int newCapacity = m_overlappingPairArray.capacity();
+
+       if (oldCapacity < newCapacity)
+       {
+               growTables();
+               //hash with new capacity
+               hash = getHash(proxyId1, proxyId2) & (m_overlappingPairArray.capacity()-1);
+       }
+       
+       pair = new (mem) btBroadphasePair(*proxy0,*proxy1);
+//     pair->m_pProxy0 = proxy0;
+//     pair->m_pProxy1 = proxy1;
+       pair->m_algorithm = 0;
+       pair->m_userInfo = 0;
+       
+
+       m_next[count] = m_hashTable[hash];
+       m_hashTable[hash] = count;
+
+       return pair;
+}
+
+
+
+void* btOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1,btDispatcher* dispatcher)
+{
+       gRemovePairs++;
+
+       int proxyId1 = proxy0->getUid();
+       int proxyId2 = proxy1->getUid();
+
+       if (proxyId1 > proxyId2) 
+               btSwap(proxyId1, proxyId2);
+
+       int hash = getHash(proxyId1, proxyId2) & (m_overlappingPairArray.capacity()-1);
+
+       btBroadphasePair* pair = internalFindPair(proxy0, proxy1, hash);
+       if (pair == NULL)
+       {
+               return 0;
+       }
+
+       cleanOverlappingPair(*pair,dispatcher);
+
+       void* userData = pair->m_userInfo;
+
+       btAssert(pair->m_pProxy0->getUid() == proxyId1);
+       btAssert(pair->m_pProxy1->getUid() == proxyId2);
+
+       int pairIndex = int(pair - &m_overlappingPairArray[0]);
+       btAssert(pairIndex < m_overlappingPairArray.size());
+
+       // Remove the pair from the hash table.
+       int index = m_hashTable[hash];
+       btAssert(index != BT_NULL_PAIR);
+
+       int previous = BT_NULL_PAIR;
+       while (index != pairIndex)
+       {
+               previous = index;
+               index = m_next[index];
+       }
+
+       if (previous != BT_NULL_PAIR)
+       {
+               btAssert(m_next[previous] == pairIndex);
+               m_next[previous] = m_next[pairIndex];
+       }
+       else
+       {
+               m_hashTable[hash] = m_next[pairIndex];
+       }
+
+       // We now move the last pair into spot of the
+       // pair being removed. We need to fix the hash
+       // table indices to support the move.
+
+       int lastPairIndex = m_overlappingPairArray.size() - 1;
+
+       // If the removed pair is the last pair, we are done.
+       if (lastPairIndex == pairIndex)
+       {
+               m_overlappingPairArray.pop_back();
+               return userData;
+       }
+
+       // Remove the last pair from the hash table.
+       const btBroadphasePair* last = &m_overlappingPairArray[lastPairIndex];
+       int lastHash = getHash(last->m_pProxy0->getUid(), last->m_pProxy1->getUid()) & (m_overlappingPairArray.capacity()-1);
+
+       index = m_hashTable[lastHash];
+       btAssert(index != BT_NULL_PAIR);
+
+       previous = BT_NULL_PAIR;
+       while (index != lastPairIndex)
+       {
+               previous = index;
+               index = m_next[index];
+       }
+
+       if (previous != BT_NULL_PAIR)
+       {
+               btAssert(m_next[previous] == lastPairIndex);
+               m_next[previous] = m_next[lastPairIndex];
+       }
+       else
+       {
+               m_hashTable[lastHash] = m_next[lastPairIndex];
+       }
+
+       // Copy the last pair into the remove pair's spot.
+       m_overlappingPairArray[pairIndex] = m_overlappingPairArray[lastPairIndex];
+
+       // Insert the last pair into the hash table
+       m_next[pairIndex] = m_hashTable[lastHash];
+       m_hashTable[lastHash] = pairIndex;
+
+       m_overlappingPairArray.pop_back();
+
+       return userData;
+}
+#include <stdio.h>
+
+void   btOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback,btDispatcher* dispatcher)
+{
+
+       int i;
+
+//     printf("m_overlappingPairArray.size()=%d\n",m_overlappingPairArray.size());
+       for (i=0;i<m_overlappingPairArray.size();)
+       {
+       
+               btBroadphasePair* pair = &m_overlappingPairArray[i];
+               if (callback->processOverlap(*pair))
+               {
+                       removeOverlappingPair(pair->m_pProxy0,pair->m_pProxy1,dispatcher);
+
+                       gOverlappingPairs--;
+               } else
+               {
+                       i++;
+               }
+       }
+}
+
+#else
+
+
+
+
+void*  btOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1, btDispatcher* dispatcher )
+{
+#ifndef USE_LAZY_REMOVAL
+
+       btBroadphasePair findPair(*proxy0,*proxy1);
+
+       int findIndex = m_overlappingPairArray.findLinearSearch(findPair);
+       if (findIndex < m_overlappingPairArray.size())
+       {
+               gOverlappingPairs--;
+               btBroadphasePair& pair = m_overlappingPairArray[findIndex];
+               void* userData = pair.m_userInfo;
+               cleanOverlappingPair(pair,dispatcher);
+               
+               m_overlappingPairArray.swap(findIndex,m_overlappingPairArray.capacity()-1);
+               m_overlappingPairArray.pop_back();
+               return userData;
+       }
+#endif //USE_LAZY_REMOVAL
+
+       return 0;
 }
 
 
 
-void   btOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback)
+
+
+
+
+
+btBroadphasePair*      btOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
+{
+       //don't add overlap with own
+       assert(proxy0 != proxy1);
+
+       if (!needsBroadphaseCollision(proxy0,proxy1))
+               return 0;
+       
+       void* mem = &m_overlappingPairArray.expand();
+       btBroadphasePair* pair = new (mem) btBroadphasePair(*proxy0,*proxy1);
+       gOverlappingPairs++;
+       return pair;
+       
+}
+
+///this findPair becomes really slow. Either sort the list to speedup the query, or
+///use a different solution. It is mainly used for Removing overlapping pairs. Removal could be delayed.
+///we could keep a linked list in each proxy, and store pair in one of the proxies (with lowest memory address)
+///Also we can use a 2D bitmap, which can be useful for a future GPU implementation
+ btBroadphasePair*     btOverlappingPairCache::findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
+{
+       if (!needsBroadphaseCollision(proxy0,proxy1))
+               return 0;
+
+       btBroadphasePair tmpPair(*proxy0,*proxy1);
+       int findIndex = m_overlappingPairArray.findLinearSearch(tmpPair);
+
+       if (findIndex < m_overlappingPairArray.size())
+       {
+               //assert(it != m_overlappingPairSet.end());
+                btBroadphasePair* pair = &m_overlappingPairArray[findIndex];
+               return pair;
+       }
+       return 0;
+}
+
+
+
+
+
+
+
+
+
+
+#include <stdio.h>
+
+void   btOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback,btDispatcher* dispatcher)
 {
 
        int i;
@@ -182,9 +457,9 @@ void        btOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callb
                btBroadphasePair* pair = &m_overlappingPairArray[i];
                if (callback->processOverlap(*pair))
                {
-                       cleanOverlappingPair(*pair);
+                       cleanOverlappingPair(*pair,dispatcher);
 
-                       m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
+                       m_overlappingPairArray.swap(i,m_overlappingPairArray.capacity()-1);
                        m_overlappingPairArray.pop_back();
                        gOverlappingPairs--;
                } else
@@ -194,3 +469,6 @@ void        btOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callb
        }
 }
 
+
+
+#endif //USE_HASH_PAIRCACHE
index a81fe3264df7a66c653d3cbf93cf98bff47112d2..a387505d1be4c4220c76dbebe4d74488ecbc0c77 100644 (file)
@@ -20,8 +20,12 @@ subject to the following restrictions:
 
 #include "btBroadphaseInterface.h"
 #include "btBroadphaseProxy.h"
-#include "../../LinearMath/btPoint3.h"
-#include "../../LinearMath/btAlignedObjectArray.h"
+#include "LinearMath/btPoint3.h"
+#include "LinearMath/btAlignedObjectArray.h"
+class btDispatcher;
+
+///disable the USE_HASH_PAIRCACHE define to use a pair manager that sorts the pairs to find duplicates/non-overlap
+#define USE_HASH_PAIRCACHE 1
 
 
 struct btOverlapCallback
@@ -40,38 +44,226 @@ struct btOverlapFilterCallback
        virtual bool    needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const = 0;
 };
 
+typedef btAlignedObjectArray<btBroadphasePair> btBroadphasePairArray;
+
+#ifdef USE_HASH_PAIRCACHE
+
+
+/// Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman, Codercorner, http://codercorner.com
+
+extern int gRemovePairs;
+extern int gAddedPairs;
+extern int gFindPairs;
+
+const int BT_NULL_PAIR=0xffffffff;
+
+class btOverlappingPairCache
+{
+       btBroadphasePairArray   m_overlappingPairArray;
+       btOverlapFilterCallback* m_overlapFilterCallback;
+       bool            m_blockedForChanges;
+
+
+public:
+       btOverlappingPairCache();
+       virtual ~btOverlappingPairCache();
+
+       
+       void    removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
+
+       void*   removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher);
+       
+       SIMD_FORCE_INLINE bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
+       {
+               if (m_overlapFilterCallback)
+                       return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1);
+
+               bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
+               collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
+               
+               return collides;
+       }
+
+       // Add a pair and return the new pair. If the pair already exists,
+       // no new pair is created and the old one is returned.
+       SIMD_FORCE_INLINE       btBroadphasePair*       addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
+       {
+               gAddedPairs++;
+
+               if (!needsBroadphaseCollision(proxy0,proxy1))
+                       return 0;
+
+               return internalAddPair(proxy0,proxy1);
+       }
+
+       
+
+       void    cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
+
+       
+       virtual void    processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher);
+
+       btBroadphasePair*       getOverlappingPairArrayPtr()
+       {
+               return &m_overlappingPairArray[0];
+       }
+
+       const btBroadphasePair* getOverlappingPairArrayPtr() const
+       {
+               return &m_overlappingPairArray[0];
+       }
+
+       btBroadphasePairArray&  getOverlappingPairArray()
+       {
+               return m_overlappingPairArray;
+       }
+
+       const btBroadphasePairArray&    getOverlappingPairArray() const
+       {
+               return m_overlappingPairArray;
+       }
+
+       void    cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher);
+
+
+
+       btBroadphasePair* findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1);
+
+       int GetCount() const { return m_overlappingPairArray.size(); }
+//     btBroadphasePair* GetPairs() { return m_pairs; }
+
+       btOverlapFilterCallback* getOverlapFilterCallback()
+       {
+               return m_overlapFilterCallback;
+       }
+
+       void setOverlapFilterCallback(btOverlapFilterCallback* callback)
+       {
+               m_overlapFilterCallback = callback;
+       }
+
+       int     getNumOverlappingPairs() const
+       {
+               return m_overlappingPairArray.size();
+       }
+private:
+       
+       btBroadphasePair*       internalAddPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
+
+       void    growTables();
+
+       SIMD_FORCE_INLINE bool equalsPair(const btBroadphasePair& pair, int proxyId1, int proxyId2)
+       {       
+               return pair.m_pProxy0->getUid() == proxyId1 && pair.m_pProxy1->getUid() == proxyId2;
+       }
+
+       /*
+       // Thomas Wang's hash, see: http://www.concentric.net/~Ttwang/tech/inthash.htm
+       // This assumes proxyId1 and proxyId2 are 16-bit.
+       SIMD_FORCE_INLINE int getHash(int proxyId1, int proxyId2)
+       {
+               int key = (proxyId2 << 16) | proxyId1;
+               key = ~key + (key << 15);
+               key = key ^ (key >> 12);
+               key = key + (key << 2);
+               key = key ^ (key >> 4);
+               key = key * 2057;
+               key = key ^ (key >> 16);
+               return key;
+       }
+       */
+
+
+       
+       SIMD_FORCE_INLINE       unsigned int getHash(unsigned int proxyId1, unsigned int proxyId2)
+       {
+               int key = ((unsigned int)proxyId1) | (((unsigned int)proxyId1) <<16);
+               // Thomas Wang's hash
+
+               key += ~(key << 15);
+               key ^=  (key >> 10);
+               key +=  (key << 3);
+               key ^=  (key >> 6);
+               key += ~(key << 11);
+               key ^=  (key >> 16);
+               return key;
+       }
+       
+
+
+
+
+       SIMD_FORCE_INLINE btBroadphasePair* internalFindPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1, int hash)
+       {
+               int proxyId1 = proxy0->getUid();
+               int proxyId2 = proxy1->getUid();
+               if (proxyId1 > proxyId2) 
+                       btSwap(proxyId1, proxyId2);
+
+               int index = m_hashTable[hash];
+               
+               while( index != BT_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false)
+               {
+                       index = m_next[index];
+               }
+
+               if ( index == BT_NULL_PAIR )
+               {
+                       return NULL;
+               }
+
+               btAssert(index < m_overlappingPairArray.size());
+
+               return &m_overlappingPairArray[index];
+       }
+
+
+public:
+       
+       btAlignedObjectArray<int>       m_hashTable;
+       btAlignedObjectArray<int>       m_next;
+       
+};
+
+
+
+#else//USE_HASH_PAIRCACHE
+
+#define USE_LAZY_REMOVAL 1
+
 ///btOverlappingPairCache maintains the objects with overlapping AABB
 ///Typically managed by the Broadphase, Axis3Sweep or btSimpleBroadphase
-class  btOverlappingPairCache : public btBroadphaseInterface
+class  btOverlappingPairCache
 {
        protected:
                //avoid brute-force finding all the time
-               btAlignedObjectArray<btBroadphasePair>  m_overlappingPairArray;
-               
+               btBroadphasePairArray   m_overlappingPairArray;
+
                //during the dispatch, check that user doesn't destroy/create proxy
                bool            m_blockedForChanges;
                
                //if set, use the callback instead of the built in filter in needBroadphaseCollision
                btOverlapFilterCallback* m_overlapFilterCallback;
+
        public:
                        
                btOverlappingPairCache();       
                virtual ~btOverlappingPairCache();
 
-               virtual void    processAllOverlappingPairs(btOverlapCallback*);
+               virtual void    processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher);
 
-               void    removeOverlappingPair(btBroadphasePair& pair);
+               void*   removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher);
 
-               void    cleanOverlappingPair(btBroadphasePair& pair);
+               void    cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher);
                
-               void    addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
+               btBroadphasePair*       addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
 
                btBroadphasePair*       findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
                        
                
-               void    cleanProxyFromPairs(btBroadphaseProxy* proxy);
+               void    cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
 
-               void    removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy);
+               void    removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
 
 
                inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
@@ -84,10 +276,19 @@ class      btOverlappingPairCache : public btBroadphaseInterface
                        
                        return collides;
                }
-                       
+               
+               btBroadphasePairArray&  getOverlappingPairArray()
+               {
+                       return m_overlappingPairArray;
+               }
+
+               const btBroadphasePairArray&    getOverlappingPairArray() const
+               {
+                       return m_overlappingPairArray;
+               }
+
                
 
-               virtual void    refreshOverlappingPairs() =0;
 
                btBroadphasePair*       getOverlappingPairArrayPtr()
                {
@@ -115,6 +316,8 @@ class       btOverlappingPairCache : public btBroadphaseInterface
                }
 
 };
+#endif //USE_HASH_PAIRCACHE
+
 #endif //OVERLAPPING_PAIR_CACHE_H
 
 
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h
new file mode 100644 (file)
index 0000000..b8d967d
--- /dev/null
@@ -0,0 +1,37 @@
+
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef OVERLAPPING_PAIR_CALLBACK_H
+#define OVERLAPPING_PAIR_CALLBACK_H
+
+///btOverlappingPairCallback provides user callback to keep track of overlap between objects, like a collision sensor
+class btOverlappingPairCallback
+{
+public:
+       virtual ~btOverlappingPairCallback()
+       {
+
+       }
+       
+       virtual void    addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) = 0;
+
+       virtual void    removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) = 0;
+
+       virtual void    removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy0) = 0;
+
+};
+
+#endif //OVERLAPPING_PAIR_CALLBACK_H
\ No newline at end of file
index 30bcbe0c5f1a73b21c5e32218ce2823001e6fe0d..e0bb0992933d8fbd71967b7f316177d222e3a6ff 100644 (file)
@@ -22,75 +22,78 @@ subject to the following restrictions:
 #include "LinearMath/btMatrix3x3.h"
 #include <new>
 
+extern int gOverlappingPairs;
 
 void   btSimpleBroadphase::validate()
 {
-       for (int i=0;i<m_numProxies;i++)
+       for (int i=0;i<m_numHandles;i++)
        {
-               for (int j=i+1;j<m_numProxies;j++)
+               for (int j=i+1;j<m_numHandles;j++)
                {
-                       assert(m_pProxies[i] != m_pProxies[j]);
+                       btAssert(&m_pHandles[i] != &m_pHandles[j]);
                }
        }
        
 }
 
-btSimpleBroadphase::btSimpleBroadphase(int maxProxies)
-       :btOverlappingPairCache(),
-       m_firstFreeProxy(0),
-       m_numProxies(0),
-       m_maxProxies(maxProxies)
+btSimpleBroadphase::btSimpleBroadphase(int maxProxies, btOverlappingPairCache* overlappingPairCache)
+       :m_pairCache(overlappingPairCache),
+       m_ownsPairCache(false),
+       m_invalidPair(0)
 {
 
-       m_proxies = new btSimpleBroadphaseProxy[maxProxies];
-       m_freeProxies = new int[maxProxies];
-       m_pProxies = new btSimpleBroadphaseProxy*[maxProxies];
-       
+       if (!overlappingPairCache)
+       {
+               void* mem = btAlignedAlloc(sizeof(btOverlappingPairCache),16);
+               m_pairCache = new (mem)btOverlappingPairCache();
+               m_ownsPairCache = true;
+       }
+
+       // allocate handles buffer and put all handles on free list
+       void* ptr = btAlignedAlloc(sizeof(btSimpleBroadphaseProxy)*maxProxies,16);
+       m_pHandles = new(ptr) btSimpleBroadphaseProxy[maxProxies];
+       m_maxHandles = maxProxies;
+       m_numHandles = 0;
+       m_firstFreeHandle = 0;
+       m_firstAllocatedHandle = -1;
 
-       int i;
-       for (i=0;i<m_maxProxies;i++)
        {
-               m_freeProxies[i] = i;
+               for (int i = m_firstFreeHandle; i < maxProxies; i++)
+               {
+                       m_pHandles[i].SetNextFree(i + 1);
+                       m_pHandles[i].m_uniqueId = i+2;//any UID will do, we just avoid too trivial values (0,1) for debugging purposes
+                       m_pHandles[i].SetNextAllocated(-1);
+               }
+               m_pHandles[maxProxies - 1].SetNextFree(0);
+               m_pHandles[maxProxies - 1].SetNextAllocated(-1);
+       
        }
+
 }
 
 btSimpleBroadphase::~btSimpleBroadphase()
 {
-       delete[] m_proxies;
-       delete []m_freeProxies;
-       delete [] m_pProxies;
+       btAlignedFree(m_pHandles);
 
-       /*int i;
-       for (i=m_numProxies-1;i>=0;i--)
+       if (m_ownsPairCache)
        {
-               BP_Proxy* proxy = m_pProxies[i]; 
-               destroyProxy(proxy);
+               m_pairCache->~btOverlappingPairCache();
+               btAlignedFree(m_pairCache);
        }
-       */
 }
 
 
-btBroadphaseProxy*     btSimpleBroadphase::createProxy(  const btVector3& min,  const btVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask)
+btBroadphaseProxy*     btSimpleBroadphase::createProxy(  const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher)
 {
-       if (m_numProxies >= m_maxProxies)
+       if (m_numHandles >= m_maxHandles)
        {
-               assert(0);
+               btAssert(0);
                return 0; //should never happen, but don't let the game crash ;-)
        }
-       assert(min[0]<= max[0] && min[1]<= max[1] && min[2]<= max[2]);
-
-       int freeIndex= m_freeProxies[m_firstFreeProxy];
-       btSimpleBroadphaseProxy* proxy = new (&m_proxies[freeIndex])btSimpleBroadphaseProxy(min,max,shapeType,userPtr,collisionFilterGroup,collisionFilterMask);
-       m_firstFreeProxy++;
-
-       btSimpleBroadphaseProxy* proxy1 = &m_proxies[0];
-               
-       int     index = int(proxy - proxy1);
-       btAssert(index == freeIndex);
+       assert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]);
 
-       m_pProxies[m_numProxies] = proxy;
-       m_numProxies++;
-       //validate();
+       int newHandleIndex = allocHandle();
+       btSimpleBroadphaseProxy* proxy = new (&m_pHandles[newHandleIndex])btSimpleBroadphaseProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask);
 
        return proxy;
 }
@@ -124,34 +127,19 @@ protected:
        };
 };
 
-void   btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg)
+void   btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg,btDispatcher* dispatcher)
 {
                
-               int i;
-               
                btSimpleBroadphaseProxy* proxy0 = static_cast<btSimpleBroadphaseProxy*>(proxyOrg);
-               btSimpleBroadphaseProxy* proxy1 = &m_proxies[0];
-       
-               int index = int(proxy0 - proxy1);
-               btAssert (index < m_maxProxies);
-               m_freeProxies[--m_firstFreeProxy] = index;
+               freeHandle(proxy0);
+
+               m_pairCache->removeOverlappingPairsContainingProxy(proxyOrg,dispatcher);
 
-               removeOverlappingPairsContainingProxy(proxyOrg);
-               
-               for (i=0;i<m_numProxies;i++)
-               {
-                       if (m_pProxies[i] == proxyOrg)
-                       {
-                               m_pProxies[i] = m_pProxies[m_numProxies-1];
-                               break;
-                       }
-               }
-               m_numProxies--;
                //validate();
                
 }
 
-void   btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax)
+void   btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)
 {
        btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy);
        sbp->m_min = aabbMin;
@@ -186,37 +174,139 @@ public:
        }
 };
 
-void   btSimpleBroadphase::refreshOverlappingPairs()
+void   btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
 {
        //first check for new overlapping pairs
        int i,j;
 
-       for (i=0;i<m_numProxies;i++)
+       if (m_firstAllocatedHandle >= 0)
        {
-               btBroadphaseProxy* proxy0 = m_pProxies[i];
-               for (j=i+1;j<m_numProxies;j++)
+
+               btSimpleBroadphaseProxy* proxy0 = &m_pHandles[m_firstAllocatedHandle];
+
+               for (i=0;i<m_numHandles;i++)
                {
-                       btBroadphaseProxy* proxy1 = m_pProxies[j];
-                       btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0);
-                       btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1);
+                       btSimpleBroadphaseProxy* proxy1 = &m_pHandles[m_firstAllocatedHandle];
 
-                       if (aabbOverlap(p0,p1))
+                       for (j=0;j<m_numHandles;j++)
                        {
-                               if ( !findPair(proxy0,proxy1))
+                               
+                               if (proxy0 != proxy1)
                                {
-                                       addOverlappingPair(proxy0,proxy1);
+                                       btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0);
+                                       btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1);
+
+                                       if (aabbOverlap(p0,p1))
+                                       {
+                                               if ( !m_pairCache->findPair(proxy0,proxy1))
+                                               {
+                                                       m_pairCache->addOverlappingPair(proxy0,proxy1);
+                                               }
+                                       } else
+                                       {
+               #ifdef USE_HASH_PAIRCACHE
+                                               if ( m_pairCache->findPair(proxy0,proxy1))
+                                               {
+                                                       m_pairCache->removeOverlappingPair(proxy0,proxy1,dispatcher);
+                                               }
+               #endif //USE_HASH_PAIRCACHE
+
+                                       }
                                }
+                               proxy1 = &m_pHandles[proxy1->GetNextAllocated()];
+
                        }
+                       proxy0 = &m_pHandles[proxy0->GetNextAllocated()];
 
                }
-       }
 
+       #ifndef USE_HASH_PAIRCACHE
 
-       CheckOverlapCallback    checkOverlap;
+               if (m_ownsPairCache)
+               {
+                       
+                       btBroadphasePairArray&  overlappingPairArray = m_pairCache->getOverlappingPairArray();
+
+                       //perform a sort, to find duplicates and to sort 'invalid' pairs to the end
+                       overlappingPairArray.heapSort(btBroadphasePairSortPredicate());
+
+                       overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
+                       m_invalidPair = 0;
+
+
+                       btBroadphasePair previousPair;
+                       previousPair.m_pProxy0 = 0;
+                       previousPair.m_pProxy1 = 0;
+                       previousPair.m_algorithm = 0;
+                       
+                       
+                       for (i=0;i<overlappingPairArray.size();i++)
+                       {
+                       
+                               btBroadphasePair& pair = overlappingPairArray[i];
 
-       processAllOverlappingPairs(&checkOverlap);
+                               bool isDuplicate = (pair == previousPair);
 
+                               previousPair = pair;
 
+                               bool needsRemoval = false;
+
+                               if (!isDuplicate)
+                               {
+                                       bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1);
+
+                                       if (hasOverlap)
+                                       {
+                                               needsRemoval = false;//callback->processOverlap(pair);
+                                       } else
+                                       {
+                                               needsRemoval = true;
+                                       }
+                               } else
+                               {
+                                       //remove duplicate
+                                       needsRemoval = true;
+                                       //should have no algorithm
+                                       btAssert(!pair.m_algorithm);
+                               }
+                               
+                               if (needsRemoval)
+                               {
+                                       m_pairCache->cleanOverlappingPair(pair,dispatcher);
+
+                       //              m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
+                       //              m_overlappingPairArray.pop_back();
+                                       pair.m_pProxy0 = 0;
+                                       pair.m_pProxy1 = 0;
+                                       m_invalidPair++;
+                                       gOverlappingPairs--;
+                               } 
+                               
+                       }
+
+               ///if you don't like to skip the invalid pairs in the array, execute following code:
+               #define CLEAN_INVALID_PAIRS 1
+               #ifdef CLEAN_INVALID_PAIRS
+
+                       //perform a sort, to sort 'invalid' pairs to the end
+                       overlappingPairArray.heapSort(btBroadphasePairSortPredicate());
+
+                       overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
+                       m_invalidPair = 0;
+               #endif//CLEAN_INVALID_PAIRS
+
+               }
+       #endif //USE_HASH_PAIRCACHE
+       }
 }
 
 
+bool btSimpleBroadphase::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
+{
+       btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0);
+       btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1);
+       return aabbOverlap(p0,p1);
+}
+
+
+
index fb155e7047c75df91653a58a9953f4daab7dfcda..09367a79d2b746924c808e84e43ae73a5046d4d9 100644 (file)
@@ -24,6 +24,10 @@ struct btSimpleBroadphaseProxy : public btBroadphaseProxy
 {
        btVector3       m_min;
        btVector3       m_max;
+       int                     m_nextFree;
+       int                     m_nextAllocated;
+//     int                     m_handleId;
+
        
        btSimpleBroadphaseProxy() {};
 
@@ -34,25 +38,64 @@ struct btSimpleBroadphaseProxy : public btBroadphaseProxy
                (void)shapeType;
        }
        
+       
+       SIMD_FORCE_INLINE void SetNextFree(int next) {m_nextFree = next;}
+       SIMD_FORCE_INLINE int GetNextFree() const {return m_nextFree;}
+
+       SIMD_FORCE_INLINE void SetNextAllocated(int next) {m_nextAllocated = next;}
+       SIMD_FORCE_INLINE int GetNextAllocated() const {return m_nextAllocated;}
+
 
 };
 
 ///SimpleBroadphase is a brute force aabb culling broadphase based on O(n^2) aabb checks
-class btSimpleBroadphase : public btOverlappingPairCache
+///btSimpleBroadphase is just a unit-test implementation to verify and test other broadphases.
+///So please don't use this class, but use bt32BitAxisSweep3 or btAxisSweep3 instead!
+class btSimpleBroadphase : public btBroadphaseInterface
 {
 
 protected:
 
-       btSimpleBroadphaseProxy*        m_proxies;
-       int*                            m_freeProxies;
-       int                             m_firstFreeProxy;
+       int             m_numHandles;                                           // number of active handles
+       int             m_maxHandles;                                           // max number of handles
+       btSimpleBroadphaseProxy* m_pHandles;                                            // handles pool
+       int             m_firstFreeHandle;              // free handles list
+       int             m_firstAllocatedHandle;
 
-       btSimpleBroadphaseProxy** m_pProxies;
-       int                             m_numProxies;
+       int allocHandle()
+       {
 
-       
+               int freeHandle = m_firstFreeHandle;
+               m_firstFreeHandle = m_pHandles[freeHandle].GetNextFree();
+               
+               m_pHandles[freeHandle].SetNextAllocated(m_firstAllocatedHandle);
+               m_firstAllocatedHandle = freeHandle;
+               
+               m_numHandles++;
+
+               return freeHandle;
+       }
+
+       void freeHandle(btSimpleBroadphaseProxy* proxy)
+       {
+               int handle = int(proxy-m_pHandles);
+               btAssert(handle >= 0 && handle < m_maxHandles);
+
+               proxy->SetNextFree(m_firstFreeHandle);
+               m_firstFreeHandle = handle;
+
+               m_firstAllocatedHandle = proxy->GetNextAllocated();
+               proxy->SetNextAllocated(-1);
+
+               m_numHandles--;
+       }
+
+
+       btOverlappingPairCache* m_pairCache;
+       bool    m_ownsPairCache;
+
+       int     m_invalidPair;
 
-       int m_maxProxies;
        
        
        inline btSimpleBroadphaseProxy* getSimpleProxyFromProxy(btBroadphaseProxy* proxy)
@@ -67,24 +110,33 @@ protected:
 protected:
 
 
-       virtual void    refreshOverlappingPairs();
+       
+
 public:
-       btSimpleBroadphase(int maxProxies=16384);
+       btSimpleBroadphase(int maxProxies=16384,btOverlappingPairCache* overlappingPairCache=0);
        virtual ~btSimpleBroadphase();
 
 
                static bool     aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1);
 
 
-       virtual btBroadphaseProxy*      createProxy(  const btVector3& min,  const btVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask);
+       virtual btBroadphaseProxy*      createProxy(  const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher);
 
+       virtual void    calculateOverlappingPairs(btDispatcher* dispatcher);
 
-       virtual void    destroyProxy(btBroadphaseProxy* proxy);
-       virtual void    setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax);
+       virtual void    destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
+       virtual void    setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher);
                
-       
-       
+       btOverlappingPairCache* getOverlappingPairCache()
+       {
+               return m_pairCache;
+       }
+       const btOverlappingPairCache*   getOverlappingPairCache() const
+       {
+               return m_pairCache;
+       }
 
+       bool    testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
 
 
 };
index e565bf7edea722cfc7ef1f504c2480508f88381d..d2d3dc6fabff7278d069ff06e5421356a9044a10 100644 (file)
@@ -8,6 +8,7 @@ ADD_LIBRARY(LibBulletCollision
                                BroadphaseCollision/btBroadphaseProxy.cpp
                                BroadphaseCollision/btCollisionAlgorithm.cpp
                                BroadphaseCollision/btDispatcher.cpp
+                               BroadphaseCollision/btMultiSapBroadphase.cpp
                                BroadphaseCollision/btOverlappingPairCache.cpp
                                BroadphaseCollision/btSimpleBroadphase.cpp
                                CollisionDispatch/btCollisionDispatcher.cpp
@@ -15,24 +16,30 @@ ADD_LIBRARY(LibBulletCollision
                                CollisionDispatch/btCollisionWorld.cpp
                                CollisionDispatch/btCompoundCollisionAlgorithm.cpp
                                CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
+                               CollisionDispatch/btDefaultCollisionConfiguration.cpp
                                CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
                                CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
+                               CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
                                CollisionDispatch/btConvexConvexAlgorithm.cpp
                                CollisionDispatch/btEmptyCollisionAlgorithm.cpp
                                CollisionDispatch/btManifoldResult.cpp
                                CollisionDispatch/btSimulationIslandManager.cpp
                                CollisionDispatch/btUnionFind.cpp
+                               CollisionDispatch/SphereTriangleDetector.cpp
                                CollisionShapes/btBoxShape.cpp
                                CollisionShapes/btBvhTriangleMeshShape.cpp
+                               CollisionShapes/btCapsuleShape.cpp
                                CollisionShapes/btCollisionShape.cpp
                                CollisionShapes/btCompoundShape.cpp
                                CollisionShapes/btConcaveShape.cpp
                                CollisionShapes/btConeShape.cpp
                                CollisionShapes/btConvexHullShape.cpp
                                CollisionShapes/btConvexShape.cpp
+                               CollisionShapes/btConvexInternalShape.cpp
                                CollisionShapes/btConvexTriangleMeshShape.cpp
                                CollisionShapes/btCylinderShape.cpp
                                CollisionShapes/btEmptyShape.cpp
+                               CollisionShapes/btHeightfieldTerrainShape.cpp
                                CollisionShapes/btMinkowskiSumShape.cpp
                                CollisionShapes/btMultiSphereShape.cpp
                                CollisionShapes/btOptimizedBvh.cpp
@@ -46,6 +53,7 @@ ADD_LIBRARY(LibBulletCollision
                                CollisionShapes/btTriangleIndexVertexArray.cpp
                                CollisionShapes/btTriangleMesh.cpp
                                CollisionShapes/btTriangleMeshShape.cpp
+                               CollisionShapes/btUniformScalingShape.cpp
                                NarrowPhaseCollision/btContinuousConvexCollision.cpp
                                NarrowPhaseCollision/btGjkEpa.cpp
                                NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
index b32806a6846874e9a9bd5ca1b98395b060eacc19..0c817b221c8ee7ca695b7db73dbaf5b5408b532a 100644 (file)
@@ -16,8 +16,8 @@ subject to the following restrictions:
 #ifndef SPHERE_TRIANGLE_DETECTOR_H
 #define SPHERE_TRIANGLE_DETECTOR_H
 
-#include "../NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
-#include "../../LinearMath/btPoint3.h"
+#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
+#include "LinearMath/btPoint3.h"
 
 
 class btSphereShape;
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h
new file mode 100644 (file)
index 0000000..fad770a
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_COLLISION_CONFIGURATION
+#define BT_COLLISION_CONFIGURATION
+struct btCollisionAlgorithmCreateFunc;
+
+class btStackAlloc;
+class btPoolAllocator;
+
+///btCollisionConfiguration allows to configure Bullet collision detection
+///stack allocator size, default collision algorithms and persistent manifold pool size
+///todo: describe the meaning
+class  btCollisionConfiguration
+{
+
+public:
+
+       virtual ~btCollisionConfiguration()
+       {
+       }
+
+       ///memory pools
+       virtual btPoolAllocator* getPersistentManifoldPool() = 0;
+
+       virtual btPoolAllocator* getCollisionAlgorithmPool() = 0;
+
+       virtual btStackAlloc*   getStackAllocator() = 0;
+
+       virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1) =0;
+
+};
+
+#endif //BT_COLLISION_CONFIGURATION
+
index d51a59af7f079dd0b21a6c5f05f16327d3c8a5fb..c6728918d16eb28fc8536613229093269d780029 100644 (file)
@@ -16,7 +16,7 @@ subject to the following restrictions:
 #ifndef COLLISION_CREATE_FUNC
 #define COLLISION_CREATE_FUNC
 
-#include "../../LinearMath/btAlignedObjectArray.h"
+#include "LinearMath/btAlignedObjectArray.h"
 typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
 class btCollisionAlgorithm;
 class btCollisionObject;
index b535fac6563e34c483029ed0400d4bd6c3a5c598..644caf2677b29278ee9eb5f32edc14dda982fb53 100644 (file)
@@ -19,69 +19,37 @@ subject to the following restrictions:
 
 
 #include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
-#include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h"
-#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h"
-#include "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h"
-#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h"
+
 #include "BulletCollision/CollisionShapes/btCollisionShape.h"
 #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
 #include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
+#include "LinearMath/btPoolAllocator.h"
+#include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h"
 
 int gNumManifold = 0;
 
 #include <stdio.h>
 
-       
-btCollisionDispatcher::btCollisionDispatcher(bool noDefaultAlgorithms):
-m_count(0),
-m_useIslands(true),
-m_convexConvexCreateFunc(0),
-m_convexConcaveCreateFunc(0),
-m_swappedConvexConcaveCreateFunc(0),
-m_compoundCreateFunc(0),
-m_swappedCompoundCreateFunc(0),
-m_emptyCreateFunc(0)
-{
-       (void)noDefaultAlgorithms;
-       int i;
-
-       setNearCallback(defaultNearCallback);
 
-       m_emptyCreateFunc = new btEmptyAlgorithm::CreateFunc;
-       for (i=0;i<MAX_BROADPHASE_COLLISION_TYPES;i++)
-       {
-               for (int j=0;j<MAX_BROADPHASE_COLLISION_TYPES;j++)
-               {
-                       m_doubleDispatch[i][j] = m_emptyCreateFunc;
-               }
-       }
-}
-//if you want to not link with the default collision algorithms, you can
-//define BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION 
-//in your Bullet library build system
-#ifndef BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION
 
-btCollisionDispatcher::btCollisionDispatcher (): 
+btCollisionDispatcher::btCollisionDispatcher (btCollisionConfiguration* collisionConfiguration): 
        m_count(0),
-       m_useIslands(true)
+       m_useIslands(true),
+       m_collisionConfiguration(collisionConfiguration)
 {
        int i;
 
        setNearCallback(defaultNearCallback);
        
-       //default CreationFunctions, filling the m_doubleDispatch table
-       m_convexConvexCreateFunc = new btConvexConvexAlgorithm::CreateFunc;
-       m_convexConcaveCreateFunc = new btConvexConcaveCollisionAlgorithm::CreateFunc;
-       m_swappedConvexConcaveCreateFunc = new btConvexConcaveCollisionAlgorithm::SwappedCreateFunc;
-       m_compoundCreateFunc = new btCompoundCollisionAlgorithm::CreateFunc;
-       m_swappedCompoundCreateFunc = new btCompoundCollisionAlgorithm::SwappedCreateFunc;
-       m_emptyCreateFunc = new btEmptyAlgorithm::CreateFunc;
+       m_collisionAlgorithmPoolAllocator = collisionConfiguration->getCollisionAlgorithmPool();
+
+       m_persistentManifoldPoolAllocator = collisionConfiguration->getPersistentManifoldPool();
 
        for (i=0;i<MAX_BROADPHASE_COLLISION_TYPES;i++)
        {
                for (int j=0;j<MAX_BROADPHASE_COLLISION_TYPES;j++)
                {
-                       m_doubleDispatch[i][j] = internalFindCreateFunc(i,j);
+                       m_doubleDispatch[i][j] = m_collisionConfiguration->getCollisionAlgorithmCreateFunc(i,j);
                        assert(m_doubleDispatch[i][j]);
                }
        }
@@ -89,8 +57,6 @@ btCollisionDispatcher::btCollisionDispatcher ():
        
 };
 
-#endif //BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION
-
 
 void btCollisionDispatcher::registerCollisionCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc)
 {
@@ -99,12 +65,6 @@ void btCollisionDispatcher::registerCollisionCreateFunc(int proxyType0, int prox
 
 btCollisionDispatcher::~btCollisionDispatcher()
 {
-       delete m_convexConvexCreateFunc;
-       delete m_convexConcaveCreateFunc;
-       delete m_swappedConvexConcaveCreateFunc;
-       delete m_compoundCreateFunc;
-       delete m_swappedCompoundCreateFunc;
-       delete m_emptyCreateFunc;
 }
 
 btPersistentManifold*  btCollisionDispatcher::getNewManifold(void* b0,void* b1) 
@@ -117,7 +77,18 @@ btPersistentManifold*       btCollisionDispatcher::getNewManifold(void* b0,void* b1)
        btCollisionObject* body0 = (btCollisionObject*)b0;
        btCollisionObject* body1 = (btCollisionObject*)b1;
        
-       btPersistentManifold* manifold = new btPersistentManifold (body0,body1);
+       void* mem = 0;
+       
+       if (m_persistentManifoldPoolAllocator->getFreeCount())
+       {
+               mem = m_persistentManifoldPoolAllocator->allocate(sizeof(btPersistentManifold));
+       } else
+       {
+               mem = btAlignedAlloc(sizeof(btPersistentManifold),16);
+
+       }
+       btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0);
+       manifold->m_index1a = m_manifoldsPtr.size();
        m_manifoldsPtr.push_back(manifold);
 
        return manifold;
@@ -137,13 +108,19 @@ void btCollisionDispatcher::releaseManifold(btPersistentManifold* manifold)
        //printf("releaseManifold: gNumManifold %d\n",gNumManifold);
        clearManifold(manifold);
 
-       ///todo: this can be improved a lot, linear search might be slow part!
-       int findIndex = m_manifoldsPtr.findLinearSearch(manifold);
-       if (findIndex < m_manifoldsPtr.size())
+       int findIndex = manifold->m_index1a;
+       btAssert(findIndex < m_manifoldsPtr.size());
+       m_manifoldsPtr.swap(findIndex,m_manifoldsPtr.size()-1);
+       m_manifoldsPtr[findIndex]->m_index1a = findIndex;
+       m_manifoldsPtr.pop_back();
+
+       manifold->~btPersistentManifold();
+       if (m_persistentManifoldPoolAllocator->validPtr(manifold))
        {
-               m_manifoldsPtr.swap(findIndex,m_manifoldsPtr.size()-1);
-               m_manifoldsPtr.pop_back();
-               delete manifold;
+               m_persistentManifoldPoolAllocator->free(manifold);
+       } else
+       {
+               btAlignedFree(manifold);
        }
        
 }
@@ -152,99 +129,19 @@ void btCollisionDispatcher::releaseManifold(btPersistentManifold* manifold)
 
 btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold)
 {
-
-#ifdef USE_DISPATCH_REGISTRY_ARRAY
        
        btCollisionAlgorithmConstructionInfo ci;
-       ci.m_dispatcher = this;
-       ci.m_manifold = sharedManifold;
-       btCollisionAlgorithm* algo = m_doubleDispatch[body0->getCollisionShape()->getShapeType()][body1->getCollisionShape()->getShapeType()]
-       ->CreateCollisionAlgorithm(ci,body0,body1);
-#else
-       btCollisionAlgorithm* algo = internalFindAlgorithm(body0,body1);
-#endif //USE_DISPATCH_REGISTRY_ARRAY
-       return algo;
-}
 
+       ci.m_dispatcher1 = this;
+       ci.m_manifold = sharedManifold;
+       btCollisionAlgorithm* algo = m_doubleDispatch[body0->getCollisionShape()->getShapeType()][body1->getCollisionShape()->getShapeType()]->CreateCollisionAlgorithm(ci,body0,body1);
 
-#ifndef BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION
-
-btCollisionAlgorithmCreateFunc* btCollisionDispatcher::internalFindCreateFunc(int proxyType0,int proxyType1)
-{
-       
-       if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConvex(proxyType1))
-       {
-               return m_convexConvexCreateFunc;
-       }
-
-       if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConcave(proxyType1))
-       {
-               return m_convexConcaveCreateFunc;
-       }
-
-       if (btBroadphaseProxy::isConvex(proxyType1) && btBroadphaseProxy::isConcave(proxyType0))
-       {
-               return m_swappedConvexConcaveCreateFunc;
-       }
-
-       if (btBroadphaseProxy::isCompound(proxyType0))
-       {
-               return m_compoundCreateFunc;
-       } else
-       {
-               if (btBroadphaseProxy::isCompound(proxyType1))
-               {
-                       return m_swappedCompoundCreateFunc;
-               }
-       }
-
-       //failed to find an algorithm
-       return m_emptyCreateFunc;
+       return algo;
 }
 
-#endif //BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION
 
 
-#ifndef USE_DISPATCH_REGISTRY_ARRAY
-
-btCollisionAlgorithm* btCollisionDispatcher::internalFindAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold)
-{
-       m_count++;
-       
-       btCollisionAlgorithmConstructionInfo ci;
-       ci.m_dispatcher = this;
-       
-       if (body0->getCollisionShape()->isConvex() && body1->getCollisionShape()->isConvex() )
-       {
-               return new btConvexConvexAlgorithm(sharedManifold,ci,body0,body1);
-       }
-
-       if (body0->getCollisionShape()->isConvex() && body1->getCollisionShape()->isConcave())
-       {
-               return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,false);
-       }
-
-       if (body1->getCollisionShape()->isConvex() && body0->getCollisionShape()->isConcave())
-       {
-               return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,true);
-       }
-
-       if (body0->getCollisionShape()->isCompound())
-       {
-               return new btCompoundCollisionAlgorithm(ci,body0,body1,false);
-       } else
-       {
-               if (body1->getCollisionShape()->isCompound())
-               {
-                       return new btCompoundCollisionAlgorithm(ci,body0,body1,true);
-               }
-       }
 
-       //failed to find an algorithm
-       return new btEmptyAlgorithm(ci);
-       
-}
-#endif //USE_DISPATCH_REGISTRY_ARRAY
 
 bool   btCollisionDispatcher::needsResponse(btCollisionObject* body0,btCollisionObject* body1)
 {
@@ -316,13 +213,13 @@ public:
 };
 
 
-void   btCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo)
+void   btCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher)
 {
        //m_blockedForChanges = true;
 
        btCollisionPairCallback collisionCallback(dispatchInfo,this);
 
-       pairCache->processAllOverlappingPairs(&collisionCallback);
+       pairCache->processAllOverlappingPairs(&collisionCallback,dispatcher);
 
        //m_blockedForChanges = false;
 
@@ -365,3 +262,26 @@ void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair,
                }
 
 }
+
+
+void* btCollisionDispatcher::allocateCollisionAlgorithm(int size)
+{
+       if (m_collisionAlgorithmPoolAllocator->getFreeCount())
+       {
+               return m_collisionAlgorithmPoolAllocator->allocate(size);
+       }
+       
+       //warn user for overflow?
+       return  btAlignedAlloc(size,16);
+}
+
+void btCollisionDispatcher::freeCollisionAlgorithm(void* ptr)
+{
+       if (m_collisionAlgorithmPoolAllocator->validPtr(ptr))
+       {
+               m_collisionAlgorithmPoolAllocator->free(ptr);
+       } else
+       {
+               btAlignedFree(ptr);
+       }
+}
index ca5aba8f01cfd7e2a2571b9612585ca9222c6262..45aaa1bd90ddb4f7f4a1b703c7c79ef00691b5b7 100644 (file)
@@ -16,17 +16,18 @@ subject to the following restrictions:
 #ifndef COLLISION__DISPATCHER_H
 #define COLLISION__DISPATCHER_H
 
-#include "../BroadphaseCollision/btDispatcher.h"
-#include "../NarrowPhaseCollision/btPersistentManifold.h"
+#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
+#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
 
-#include "../CollisionDispatch/btManifoldResult.h"
+#include "BulletCollision/CollisionDispatch/btManifoldResult.h"
 
-#include "../BroadphaseCollision/btBroadphaseProxy.h"
-#include "../../LinearMath/btAlignedObjectArray.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "LinearMath/btAlignedObjectArray.h"
 
 class btIDebugDraw;
 class btOverlappingPairCache;
-
+class btPoolAllocator;
+class btCollisionConfiguration;
 
 #include "btCollisionCreateFunc.h"
 
@@ -51,21 +52,15 @@ class btCollisionDispatcher : public btDispatcher
 
        btNearCallback          m_nearCallback;
        
+       btPoolAllocator*        m_collisionAlgorithmPoolAllocator;
+
+       btPoolAllocator*        m_persistentManifoldPoolAllocator;
+
        btCollisionAlgorithmCreateFunc* m_doubleDispatch[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES];
        
-       btCollisionAlgorithmCreateFunc* internalFindCreateFunc(int proxyType0,int proxyType1);
 
-       //default CreationFunctions, filling the m_doubleDispatch table
-       btCollisionAlgorithmCreateFunc* m_convexConvexCreateFunc;
-       btCollisionAlgorithmCreateFunc* m_convexConcaveCreateFunc;
-       btCollisionAlgorithmCreateFunc* m_swappedConvexConcaveCreateFunc;
-       btCollisionAlgorithmCreateFunc* m_compoundCreateFunc;
-       btCollisionAlgorithmCreateFunc* m_swappedCompoundCreateFunc;
-       btCollisionAlgorithmCreateFunc*   m_emptyCreateFunc;
+       btCollisionConfiguration*       m_collisionConfiguration;
 
-#ifndef USE_DISPATCH_REGISTRY_ARRAY
-       btCollisionAlgorithm* internalFindAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold = 0);
-#endif //USE_DISPATCH_REGISTRY_ARRAY
 
 public:
 
@@ -92,11 +87,7 @@ public:
                return m_manifoldsPtr[index];
        }
 
-       ///the default constructor creates/register default collision algorithms, for convex, compound and concave shape support
-       btCollisionDispatcher ();
-
-       ///a special constructor that doesn't create/register the default collision algorithms
-       btCollisionDispatcher(bool noDefaultAlgorithms);
+       btCollisionDispatcher (btCollisionConfiguration* collisionConfiguration);
 
        virtual ~btCollisionDispatcher();
 
@@ -114,7 +105,7 @@ public:
        
        virtual bool    needsResponse(btCollisionObject* body0,btCollisionObject* body1);
        
-       virtual void    dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo);
+       virtual void    dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher);
 
        void    setNearCallback(btNearCallback  nearCallback)
        {
@@ -129,6 +120,25 @@ public:
        //by default, Bullet will use this near callback
        static void  defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, btDispatcherInfo& dispatchInfo);
 
+       virtual void* allocateCollisionAlgorithm(int size);
+
+       virtual void freeCollisionAlgorithm(void* ptr);
+
+       btCollisionConfiguration*       getCollisionConfiguration()
+       {
+               return m_collisionConfiguration;
+       }
+
+       const btCollisionConfiguration* getCollisionConfiguration() const
+       {
+               return m_collisionConfiguration;
+       }
+
+       void    setCollisionConfiguration(btCollisionConfiguration* config)
+       {
+               m_collisionConfiguration = config;
+       }
+
 };
 
 #endif //COLLISION__DISPATCHER_H
index d4c0a4e8cb335a289073c298af7f8383d1131d64..6b72a131c4f1da83ec5b0a31b735fcb63bb0cbae 100644 (file)
@@ -13,15 +13,19 @@ subject to the following restrictions:
 3. This notice may not be removed or altered from any source distribution.
 */
 
+
 #include "btCollisionObject.h"
 
 btCollisionObject::btCollisionObject()
        :       m_broadphaseHandle(0),
                m_collisionShape(0),
                m_collisionFlags(0),
+               m_islandTag1(-1),
+               m_companionId(-1),
                m_activationState1(1),
                m_deactivationTime(btScalar(0.)),
                m_userObjectPointer(0),
+               m_internalOwner(0),
                m_hitFraction(btScalar(1.)),
                m_ccdSweptSphereRadius(btScalar(0.)),
                m_ccdSquareMotionThreshold(btScalar(0.)),
@@ -55,3 +59,4 @@ void btCollisionObject::activate(bool forceActivation)
 }
 
 
+
index 9fb6a67c4a30130805ce22f615e4e0d35097bccf..7c1ddbf1e2daee7a7dbf2212c1708ca907e51d72 100644 (file)
@@ -16,7 +16,7 @@ subject to the following restrictions:
 #ifndef COLLISION_OBJECT_H
 #define COLLISION_OBJECT_H
 
-#include "../../LinearMath/btTransform.h"
+#include "LinearMath/btTransform.h"
 
 //island management, m_activationState1
 #define ACTIVE_TAG 1
@@ -27,7 +27,8 @@ subject to the following restrictions:
 
 struct btBroadphaseProxy;
 class  btCollisionShape;
-#include "../../LinearMath/btMotionState.h"
+#include "LinearMath/btMotionState.h"
+#include "LinearMath/btAlignedAllocator.h"
 
 
 
@@ -89,6 +90,8 @@ protected:
 
 public:
 
+       BT_DECLARE_ALIGNED_ALLOCATOR();
+
        enum CollisionFlags
        {
                CF_STATIC_OBJECT= 1,
@@ -98,28 +101,28 @@ public:
        };
 
 
-       inline bool mergesSimulationIslands() const
+       SIMD_FORCE_INLINE bool mergesSimulationIslands() const
        {
                ///static objects, kinematic and object without contact response don't merge islands
                return  ((m_collisionFlags & (CF_STATIC_OBJECT | CF_KINEMATIC_OBJECT | CF_NO_CONTACT_RESPONSE) )==0);
        }
 
 
-       inline bool             isStaticObject() const {
+       SIMD_FORCE_INLINE bool          isStaticObject() const {
                return (m_collisionFlags & CF_STATIC_OBJECT) != 0;
        }
 
-       inline bool             isKinematicObject() const
+       SIMD_FORCE_INLINE bool          isKinematicObject() const
        {
                return (m_collisionFlags & CF_KINEMATIC_OBJECT) != 0;
        }
 
-       inline bool             isStaticOrKinematicObject() const
+       SIMD_FORCE_INLINE bool          isStaticOrKinematicObject() const
        {
                return (m_collisionFlags & (CF_KINEMATIC_OBJECT | CF_STATIC_OBJECT)) != 0 ;
        }
 
-       inline bool             hasContactResponse() const {
+       SIMD_FORCE_INLINE bool          hasContactResponse() const {
                return (m_collisionFlags & CF_NO_CONTACT_RESPONSE)==0;
        }
 
@@ -133,12 +136,12 @@ public:
                m_collisionShape = collisionShape;
        }
 
-       const btCollisionShape* getCollisionShape() const
+       SIMD_FORCE_INLINE const btCollisionShape*       getCollisionShape() const
        {
                return m_collisionShape;
        }
 
-       btCollisionShape*       getCollisionShape()
+       SIMD_FORCE_INLINE btCollisionShape*     getCollisionShape()
        {
                return m_collisionShape;
        }
index b49036a5b50322b12b27e726b9024ebb0241d3b7..b4828508bcb3dd23867ff5008cbf1725a1890657 100644 (file)
@@ -24,6 +24,9 @@ subject to the following restrictions:
 #include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h"
 #include "BulletCollision/CollisionShapes/btCompoundShape.h"
 #include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h"
+#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h"
+
 #include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
 #include "LinearMath/btAabbUtil2.h"
 #include "LinearMath/btQuickprof.h"
@@ -32,23 +35,20 @@ subject to the following restrictions:
 //When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor)
 #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
 #include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
+#include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h"
 
 
-btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache, int stackSize)
+btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache, btCollisionConfiguration* collisionConfiguration)
 :m_dispatcher1(dispatcher),
-m_broadphasePairCache(pairCache),
-m_ownsDispatcher(false),
-m_ownsBroadphasePairCache(false)
+m_broadphasePairCache(pairCache)
 {
-       m_stackAlloc = new btStackAlloc(stackSize);
+       m_stackAlloc = collisionConfiguration->getStackAllocator();
        m_dispatchInfo.m_stackAllocator = m_stackAlloc;
 }
 
 
 btCollisionWorld::~btCollisionWorld()
 {
-       m_stackAlloc->destroy();
-       delete m_stackAlloc;
 
        //clean up remaining objects
        int i;
@@ -62,15 +62,11 @@ btCollisionWorld::~btCollisionWorld()
                        //
                        // only clear the cached algorithms
                        //
-                       getBroadphase()->cleanProxyFromPairs(bp);
-                       getBroadphase()->destroyProxy(bp);
+                       getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1);
+                       getBroadphase()->destroyProxy(bp,m_dispatcher1);
                }
        }
 
-       if (m_ownsDispatcher)
-               delete m_dispatcher1;
-       if (m_ownsBroadphasePairCache)
-               delete m_broadphasePairCache;
 
 }
 
@@ -105,7 +101,8 @@ void        btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,sho
                        type,
                        collisionObject,
                        collisionFilterGroup,
-                       collisionFilterMask
+                       collisionFilterMask,
+                       m_dispatcher1
                        ))      ;
 
                
@@ -130,11 +127,10 @@ void      btCollisionWorld::performDiscreteCollisionDetection()
        for (int i=0;i<m_collisionObjects.size();i++)
        {
                m_collisionObjects[i]->getCollisionShape()->getAabb(m_collisionObjects[i]->getWorldTransform(),aabbMin,aabbMax);
-               m_broadphasePairCache->setAabb(m_collisionObjects[i]->getBroadphaseHandle(),aabbMin,aabbMax);
+               m_broadphasePairCache->setAabb(m_collisionObjects[i]->getBroadphaseHandle(),aabbMin,aabbMax,m_dispatcher1);
        }
 
-       m_broadphasePairCache->refreshOverlappingPairs();
-
+       m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1);
        
        END_PROFILE("perform Broadphase Collision Detection");
 
@@ -142,13 +138,14 @@ void      btCollisionWorld::performDiscreteCollisionDetection()
 
        btDispatcher* dispatcher = getDispatcher();
        if (dispatcher)
-               dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache,dispatchInfo);
+               dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo,m_dispatcher1);
 
        END_PROFILE("performDiscreteCollisionDetection");
 
 }
 
 
+
 void   btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject)
 {
        
@@ -163,8 +160,8 @@ void        btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject)
                        //
                        // only clear the cached algorithms
                        //
-                       getBroadphase()->cleanProxyFromPairs(bp);
-                       getBroadphase()->destroyProxy(bp);
+                       getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1);
+                       getBroadphase()->destroyProxy(bp,m_dispatcher1);
                        collisionObject->setBroadphaseHandle(0);
                }
        }
@@ -209,19 +206,28 @@ void      btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
 
                                btConvexShape* convexShape = (btConvexShape*) collisionShape;
                                btVoronoiSimplexSolver  simplexSolver;
+#define  USE_SUBSIMPLEX_CONVEX_CAST 1
+#ifdef USE_SUBSIMPLEX_CONVEX_CAST
                                btSubsimplexConvexCast convexCaster(castShape,convexShape,&simplexSolver);
-                               //GjkConvexCast convexCaster(castShape,convexShape,&simplexSolver);
-                               //ContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
-                               
+#else
+                               //btGjkConvexCast       convexCaster(castShape,convexShape,&simplexSolver);
+                               //btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
+#endif //#USE_SUBSIMPLEX_CONVEX_CAST
+                       
                                if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
                                {
                                        //add hit
                                        if (castResult.m_normal.length2() > btScalar(0.0001))
                                        {
-                                               castResult.m_normal.normalize();
+                                               
                                                if (castResult.m_fraction < resultCallback.m_closestHitFraction)
                                                {
+#ifdef USE_SUBSIMPLEX_CONVEX_CAST
+                                                       //rotate normal into worldspace
+                                                       castResult.m_normal = rayFromTrans.getBasis() * castResult.m_normal;
+#endif //USE_SUBSIMPLEX_CONVEX_CAST
 
+                                                       castResult.m_normal.normalize();
                                                        btCollisionWorld::LocalRayResult localRayResult
                                                                (
                                                                        collisionObject, 
@@ -230,7 +236,8 @@ void        btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
                                                                        castResult.m_fraction
                                                                );
 
-                                                       resultCallback.AddSingleResult(localRayResult);
+                                                       bool normalInWorldSpace = true;
+                                                       resultCallback.AddSingleResult(localRayResult, normalInWorldSpace);
 
                                                }
                                        }
@@ -279,7 +286,8 @@ void        btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
                                                                        hitNormalLocal,
                                                                        hitFraction);
                                                                
-                                                               return m_resultCallback->AddSingleResult(rayResult);
+                                                               bool    normalInWorldSpace = false;
+                                                               return m_resultCallback->AddSingleResult(rayResult,normalInWorldSpace);
                                                                
                                                                
                                                        }
index b6d80233ab7acbd927774aed8dc188e5e90f5e92..bda03ccedebe55b69e6fce6da2231802eedfa417 100644 (file)
@@ -68,12 +68,12 @@ class btStackAlloc;
 class btCollisionShape;
 class btConvexShape;
 class btBroadphaseInterface;
-#include "../../LinearMath/btVector3.h"
-#include "../../LinearMath/btTransform.h"
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btTransform.h"
 #include "btCollisionObject.h"
 #include "btCollisionDispatcher.h" //for definition of btCollisionObjectArray
-#include "../BroadphaseCollision/btOverlappingPairCache.h"
-#include "../../LinearMath/btAlignedObjectArray.h"
+#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
+#include "LinearMath/btAlignedObjectArray.h"
 
 ///CollisionWorld is interface and container for the collision detection
 class btCollisionWorld
@@ -90,15 +90,12 @@ protected:
 
        btStackAlloc*   m_stackAlloc;
 
-       btOverlappingPairCache* m_broadphasePairCache;
+       btBroadphaseInterface*  m_broadphasePairCache;
        
-       bool    m_ownsDispatcher;
-       bool    m_ownsBroadphasePairCache;
-
 public:
 
        //this constructor doesn't own the dispatcher and paircache/broadphase
-       btCollisionWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache, int stackSize = 2*1024*1024);
+       btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphasePairCache, btCollisionConfiguration* collisionConfiguration);
 
        virtual ~btCollisionWorld();
 
@@ -110,7 +107,7 @@ public:
 
        btOverlappingPairCache* getPairCache()
        {
-               return m_broadphasePairCache;
+               return m_broadphasePairCache->getOverlappingPairCache();
        }
 
 
@@ -166,7 +163,7 @@ public:
                        :m_closestHitFraction(btScalar(1.))
                {
                }
-               virtual btScalar        AddSingleResult(LocalRayResult& rayResult) = 0;
+               virtual btScalar        AddSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace) = 0;
        };
 
        struct  ClosestRayResultCallback : public RayResultCallback
@@ -185,7 +182,7 @@ public:
                btVector3       m_hitPointWorld;
                btCollisionObject*      m_collisionObject;
                
-               virtual btScalar        AddSingleResult(LocalRayResult& rayResult)
+               virtual btScalar        AddSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace)
                {
 
 //caller already does the filter on the m_closestHitFraction
@@ -193,7 +190,14 @@ public:
                        
                        m_closestHitFraction = rayResult.m_hitFraction;
                        m_collisionObject = rayResult.m_collisionObject;
-                       m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal;
+                       if (normalInWorldSpace)
+                       {
+                               m_hitNormalWorld = rayResult.m_hitNormalLocal;
+                       } else
+                       {
+                               ///need to transform normal into worldspace
+                               m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal;
+                       }
                        m_hitPointWorld.setInterpolate3(m_rayFromWorld,m_rayToWorld,rayResult.m_hitFraction);
                        return rayResult.m_hitFraction;
                }
index 92f4c8b28a6d935f0e9c46b980d5d35c97c41596..7c0c7a3b0a97b9ceab918917ec2fadef130a6fc9 100644 (file)
@@ -19,7 +19,8 @@ subject to the following restrictions:
 
 
 btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
-:m_isSwapped(isSwapped)
+:btCollisionAlgorithm(ci),
+m_isSwapped(isSwapped)
 {
        btCollisionObject* colObj = m_isSwapped? body1 : body0;
        btCollisionObject* otherObj = m_isSwapped? body0 : body1;
@@ -35,7 +36,7 @@ btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlg
                btCollisionShape* childShape = compoundShape->getChildShape(i);
                btCollisionShape* orgShape = colObj->getCollisionShape();
                colObj->setCollisionShape( childShape );
-               m_childCollisionAlgorithms[i] = ci.m_dispatcher->findAlgorithm(colObj,otherObj);
+               m_childCollisionAlgorithms[i] = ci.m_dispatcher1->findAlgorithm(colObj,otherObj);
                colObj->setCollisionShape( orgShape );
        }
 }
@@ -47,7 +48,8 @@ btCompoundCollisionAlgorithm::~btCompoundCollisionAlgorithm()
        int i;
        for (i=0;i<numChildren;i++)
        {
-               delete m_childCollisionAlgorithms[i];
+               m_childCollisionAlgorithms[i]->~btCollisionAlgorithm();
+               m_dispatcher->freeCollisionAlgorithm(m_childCollisionAlgorithms[i]);
        }
 }
 
index 7091b233b4636c5fbd4c739eb7e18be46e513045..a381d8b3c3f4f6efd06462984adb382071716e9d 100644 (file)
@@ -16,15 +16,16 @@ subject to the following restrictions:
 #ifndef COMPOUND_COLLISION_ALGORITHM_H
 #define COMPOUND_COLLISION_ALGORITHM_H
 
-#include "../BroadphaseCollision/btCollisionAlgorithm.h"
-#include "../BroadphaseCollision/btDispatcher.h"
-#include "../BroadphaseCollision/btBroadphaseInterface.h"
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
 
-#include "../NarrowPhaseCollision/btPersistentManifold.h"
+#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
 class btDispatcher;
-#include "../BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
 #include "btCollisionCreateFunc.h"
-#include "../../LinearMath/btAlignedObjectArray.h"
+#include "LinearMath/btAlignedObjectArray.h"
+class btDispatcher;
 
 /// btCompoundCollisionAlgorithm  supports collision between CompoundCollisionShapes and other collision shapes
 /// Place holder, not fully implemented yet
@@ -47,7 +48,8 @@ public:
        {
                virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
                {
-                       return new btCompoundCollisionAlgorithm(ci,body0,body1,false);
+                       void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCollisionAlgorithm));
+                       return new(mem) btCompoundCollisionAlgorithm(ci,body0,body1,false);
                }
        };
 
@@ -55,7 +57,8 @@ public:
        {
                virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
                {
-                       return new btCompoundCollisionAlgorithm(ci,body0,body1,true);
+                       void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCollisionAlgorithm));
+                       return new(mem) btCompoundCollisionAlgorithm(ci,body0,body1,true);
                }
        };
 
index 24ceacfd40dd1d5999b141bf2442bdc55809d459..559b633feb91847d7679239acc1c3f49610ed918 100644 (file)
@@ -29,7 +29,7 @@ subject to the following restrictions:
 btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
 : btCollisionAlgorithm(ci),
 m_isSwapped(isSwapped),
-m_btConvexTriangleCallback(ci.m_dispatcher,body0,body1,isSwapped)
+m_btConvexTriangleCallback(ci.m_dispatcher1,body0,body1,isSwapped)
 {
 }
 
@@ -79,7 +79,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
        //aabb filter is already applied!       
 
        btCollisionAlgorithmConstructionInfo ci;
-       ci.m_dispatcher = m_dispatcher;
+       ci.m_dispatcher1 = m_dispatcher;
 
        btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
 
@@ -115,7 +115,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
                ob->setCollisionShape( &tm );
                
 
-               btCollisionAlgorithm* colAlgo = ci.m_dispatcher->findAlgorithm(m_convexBody,m_triBody,m_manifoldPtr);
+               btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBody,m_triBody,m_manifoldPtr);
                ///this should use the btDispatcher, so the actual registered algorithm is used
                //              btConvexConvexAlgorithm cvxcvxalgo(m_manifoldPtr,ci,m_convexBody,m_triBody);
 
@@ -123,7 +123,8 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
        //      cvxcvxalgo.setShapeIdentifiers(-1,-1,partId,triangleIndex);
 //             cvxcvxalgo.processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
                colAlgo->processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
-               delete colAlgo;
+               colAlgo->~btCollisionAlgorithm();
+               ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
                ob->setCollisionShape( tmpShape );
 
        }
@@ -188,9 +189,10 @@ void btConvexConcaveCollisionAlgorithm::processCollision (btCollisionObject* bod
 
                        concaveShape->processAllTriangles( &m_btConvexTriangleCallback,m_btConvexTriangleCallback.getAabbMin(),m_btConvexTriangleCallback.getAabbMax());
                        
+                       resultOut->refreshContactPoints();
        
                }
-
+       
        }
 
 }
index 4915b6c20c8d8928b79d00344e49ba2a8d8f2fe4..da33e98899188370ba13cf82a0613e01ae086534 100644 (file)
@@ -16,13 +16,13 @@ subject to the following restrictions:
 #ifndef CONVEX_CONCAVE_COLLISION_ALGORITHM_H
 #define CONVEX_CONCAVE_COLLISION_ALGORITHM_H
 
-#include "../BroadphaseCollision/btCollisionAlgorithm.h"
-#include "../BroadphaseCollision/btDispatcher.h"
-#include "../BroadphaseCollision/btBroadphaseInterface.h"
-#include "../CollisionShapes/btTriangleCallback.h"
-#include "../NarrowPhaseCollision/btPersistentManifold.h"
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
+#include "BulletCollision/CollisionShapes/btTriangleCallback.h"
+#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
 class btDispatcher;
-#include "../BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
 #include "btCollisionCreateFunc.h"
 
 ///For each triangle in the concave mesh that overlaps with the AABB of a convex (m_convexProxy), processTriangle is called.
@@ -55,11 +55,11 @@ int m_triangleCount;
        
        void clearCache();
 
-       inline const btVector3& getAabbMin() const
+       SIMD_FORCE_INLINE const btVector3& getAabbMin() const
        {
                return m_aabbMin;
        }
-       inline const btVector3& getAabbMax() const
+       SIMD_FORCE_INLINE const btVector3& getAabbMax() const
        {
                return m_aabbMax;
        }
@@ -94,7 +94,8 @@ public:
        {
                virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
                {
-                       return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,false);
+                       void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConcaveCollisionAlgorithm));
+                       return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0,body1,false);
                }
        };
 
@@ -102,7 +103,8 @@ public:
        {
                virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
                {
-                       return new btConvexConcaveCollisionAlgorithm(ci,body0,body1,true);
+                       void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConcaveCollisionAlgorithm));
+                       return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0,body1,true);
                }
        };
 
index 9105fe20b49622c3b37f6214cb5ab5b0ebe3e4b5..d1692cdac694b9a93d81e407def84aa135b6cd22 100644 (file)
@@ -48,26 +48,16 @@ subject to the following restrictions:
 
 
 
-btConvexConvexAlgorithm::CreateFunc::CreateFunc()
-{
-       m_ownsSolvers = true;
-       m_simplexSolver = new btVoronoiSimplexSolver();
-       m_pdSolver = new btGjkEpaPenetrationDepthSolver;
-}
+
 
 btConvexConvexAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface*                      simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
 {
-       m_ownsSolvers = false;
        m_simplexSolver = simplexSolver;
        m_pdSolver = pdSolver;
 }
 
 btConvexConvexAlgorithm::CreateFunc::~CreateFunc() 
 { 
-   if (m_ownsSolvers){ 
-      delete m_simplexSolver; 
-      delete m_pdSolver; 
-   } 
 }
 
 btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
@@ -152,6 +142,11 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
        m_gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
 #endif
 
+       if (m_ownManifold)
+       {
+               resultOut->refreshContactPoints();
+       }
+
 }
 
 
index cbea9a92b75e4b1f9da1af1a74588f8601c9ff2e..ca58bce25f11d3205c6a52d5932202fe817c8044 100644 (file)
@@ -16,12 +16,13 @@ subject to the following restrictions:
 #ifndef CONVEX_CONVEX_ALGORITHM_H
 #define CONVEX_CONVEX_ALGORITHM_H
 
-#include "../BroadphaseCollision/btCollisionAlgorithm.h"
-#include "../NarrowPhaseCollision/btGjkPairDetector.h"
-#include "../NarrowPhaseCollision/btPersistentManifold.h"
-#include "../BroadphaseCollision/btBroadphaseProxy.h"
-#include "../NarrowPhaseCollision/btVoronoiSimplexSolver.h"
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
+#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
 #include "btCollisionCreateFunc.h"
+#include "btCollisionDispatcher.h"
 
 class btConvexPenetrationDepthSolver;
 
@@ -58,15 +59,15 @@ public:
        {
                btConvexPenetrationDepthSolver*         m_pdSolver;
                btSimplexSolverInterface*                       m_simplexSolver;
-               bool    m_ownsSolvers;
                
                CreateFunc(btSimplexSolverInterface*                    simplexSolver, btConvexPenetrationDepthSolver* pdSolver);
-               CreateFunc();
+               
                virtual ~CreateFunc();
 
                virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
                {
-                       return new btConvexConvexAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver);
+                       void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConvexAlgorithm));
+                       return new(mem) btConvexConvexAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver);
                }
        };
 
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp
new file mode 100644 (file)
index 0000000..661270b
--- /dev/null
@@ -0,0 +1,237 @@
+
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "btDefaultCollisionConfiguration.h"
+
+#include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
+#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
+
+
+
+#include "LinearMath/btStackAlloc.h"
+#include "LinearMath/btPoolAllocator.h"
+
+
+
+#define DEFAULT_MAX_OVERLAPPING_PAIRS 65535
+#define DEFAULT_STACK_ALLOCATOR_SIZE   (5*1024*1024)
+
+
+btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(btStackAlloc* stackAlloc,btPoolAllocator*     persistentManifoldPool,btPoolAllocator* collisionAlgorithmPool)
+{
+
+       void* mem = btAlignedAlloc(sizeof(btVoronoiSimplexSolver),16);
+       m_simplexSolver = new (mem)btVoronoiSimplexSolver();
+       mem = btAlignedAlloc(sizeof(btGjkEpaPenetrationDepthSolver),16);
+       m_pdSolver = new (mem)btGjkEpaPenetrationDepthSolver;
+
+       //default CreationFunctions, filling the m_doubleDispatch table
+       mem = btAlignedAlloc(sizeof(btConvexConvexAlgorithm::CreateFunc),16);
+       m_convexConvexCreateFunc = new(mem) btConvexConvexAlgorithm::CreateFunc(m_simplexSolver,m_pdSolver);
+       mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16);
+       m_convexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::CreateFunc;
+       mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16);
+       m_swappedConvexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::SwappedCreateFunc;
+       mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::CreateFunc),16);
+       m_compoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::CreateFunc;
+       mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::SwappedCreateFunc),16);
+       m_swappedCompoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::SwappedCreateFunc;
+       mem = btAlignedAlloc(sizeof(btEmptyAlgorithm::CreateFunc),16);
+       m_emptyCreateFunc = new(mem) btEmptyAlgorithm::CreateFunc;
+
+       mem = btAlignedAlloc(sizeof(btSphereSphereCollisionAlgorithm::CreateFunc),16);
+       m_sphereSphereCF = new(mem) btSphereSphereCollisionAlgorithm::CreateFunc;
+       mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc),16);
+       m_sphereBoxCF = new(mem) btSphereBoxCollisionAlgorithm::CreateFunc;
+       mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc),16);
+       m_boxSphereCF = new (mem)btSphereBoxCollisionAlgorithm::CreateFunc;
+       m_boxSphereCF->m_swapped = true;
+       mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc),16);
+       m_sphereTriangleCF = new (mem)btSphereTriangleCollisionAlgorithm::CreateFunc;
+       mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc),16);
+       m_triangleSphereCF = new (mem)btSphereTriangleCollisionAlgorithm::CreateFunc;
+       m_triangleSphereCF->m_swapped = true;
+
+
+       ///calculate maximum element size, big enough to fit any collision algorithm in the memory pool
+       int maxSize = sizeof(btConvexConvexAlgorithm);
+       int maxSize2 = sizeof(btConvexConcaveCollisionAlgorithm);
+       int maxSize3 = sizeof(btCompoundCollisionAlgorithm);
+       int maxSize4 = sizeof(btEmptyAlgorithm);
+       
+       int     collisionAlgorithmMaxElementSize = btMax(maxSize,maxSize2);
+       collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3);
+       collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize4);
+
+       if (stackAlloc)
+       {
+               m_ownsStackAllocator = false;
+               this->m_stackAlloc = stackAlloc;
+       } else
+       {
+               m_ownsStackAllocator = true;
+               void* mem = btAlignedAlloc(sizeof(btStackAlloc),16);
+               m_stackAlloc = new(mem)btStackAlloc(DEFAULT_STACK_ALLOCATOR_SIZE);
+       }
+               
+       if (persistentManifoldPool)
+       {
+               m_ownsPersistentManifoldPool = false;
+               m_persistentManifoldPool = persistentManifoldPool;
+       } else
+       {
+               m_ownsPersistentManifoldPool = true;
+               void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16);
+               m_persistentManifoldPool = new (mem) btPoolAllocator(sizeof(btPersistentManifold),DEFAULT_MAX_OVERLAPPING_PAIRS);
+       }
+       
+       if (collisionAlgorithmPool)
+       {
+               m_ownsCollisionAlgorithmPool = false;
+               m_collisionAlgorithmPool = collisionAlgorithmPool;
+       } else
+       {
+               m_ownsCollisionAlgorithmPool = true;
+               void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16);
+               m_collisionAlgorithmPool = new(mem) btPoolAllocator(collisionAlgorithmMaxElementSize,DEFAULT_MAX_OVERLAPPING_PAIRS);
+       }
+
+
+}
+
+btDefaultCollisionConfiguration::~btDefaultCollisionConfiguration()
+{
+       if (m_ownsStackAllocator)
+       {
+               m_stackAlloc->destroy();
+               m_stackAlloc->~btStackAlloc();
+               btAlignedFree(m_stackAlloc);
+       }
+       if (m_ownsCollisionAlgorithmPool)
+       {
+               m_collisionAlgorithmPool->~btPoolAllocator();
+               btAlignedFree(m_collisionAlgorithmPool);
+       }
+       if (m_ownsPersistentManifoldPool)
+       {
+               m_persistentManifoldPool->~btPoolAllocator();
+               btAlignedFree(m_persistentManifoldPool);
+       }
+
+       m_convexConvexCreateFunc->~btCollisionAlgorithmCreateFunc();
+       btAlignedFree(  m_convexConvexCreateFunc);
+
+       m_convexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc();
+       btAlignedFree( m_convexConcaveCreateFunc);
+       m_swappedConvexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc();
+       btAlignedFree( m_swappedConvexConcaveCreateFunc);
+
+       m_compoundCreateFunc->~btCollisionAlgorithmCreateFunc();
+       btAlignedFree( m_compoundCreateFunc);
+
+       m_swappedCompoundCreateFunc->~btCollisionAlgorithmCreateFunc();
+       btAlignedFree( m_swappedCompoundCreateFunc);
+
+       m_emptyCreateFunc->~btCollisionAlgorithmCreateFunc();
+       btAlignedFree( m_emptyCreateFunc);
+
+       m_sphereSphereCF->~btCollisionAlgorithmCreateFunc();
+       btAlignedFree( m_sphereSphereCF);
+
+       m_sphereBoxCF->~btCollisionAlgorithmCreateFunc();
+       btAlignedFree( m_sphereBoxCF);
+       m_boxSphereCF->~btCollisionAlgorithmCreateFunc();
+       btAlignedFree( m_boxSphereCF);
+       m_sphereTriangleCF->~btCollisionAlgorithmCreateFunc();
+       btAlignedFree( m_sphereTriangleCF);
+       m_triangleSphereCF->~btCollisionAlgorithmCreateFunc();
+       btAlignedFree( m_triangleSphereCF);
+
+       m_simplexSolver->~btVoronoiSimplexSolver();
+       btAlignedFree(m_simplexSolver);
+       m_pdSolver->~btGjkEpaPenetrationDepthSolver();
+       btAlignedFree(m_pdSolver);
+
+
+}
+
+
+btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1)
+{
+       
+
+       if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1==SPHERE_SHAPE_PROXYTYPE))
+       {
+               return  m_sphereSphereCF;
+       }
+
+       if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1==BOX_SHAPE_PROXYTYPE))
+       {
+               return  m_sphereBoxCF;
+       }
+
+       if ((proxyType0 == BOX_SHAPE_PROXYTYPE ) && (proxyType1==SPHERE_SHAPE_PROXYTYPE))
+       {
+               return  m_boxSphereCF;
+       }
+
+       if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE ) && (proxyType1==TRIANGLE_SHAPE_PROXYTYPE))
+       {
+               return  m_sphereTriangleCF;
+       }
+
+       if ((proxyType0 == TRIANGLE_SHAPE_PROXYTYPE  ) && (proxyType1==SPHERE_SHAPE_PROXYTYPE))
+       {
+               return  m_triangleSphereCF;
+       }
+       
+
+       if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConvex(proxyType1))
+       {
+               return m_convexConvexCreateFunc;
+       }
+
+       if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConcave(proxyType1))
+       {
+               return m_convexConcaveCreateFunc;
+       }
+
+       if (btBroadphaseProxy::isConvex(proxyType1) && btBroadphaseProxy::isConcave(proxyType0))
+       {
+               return m_swappedConvexConcaveCreateFunc;
+       }
+
+       if (btBroadphaseProxy::isCompound(proxyType0))
+       {
+               return m_compoundCreateFunc;
+       } else
+       {
+               if (btBroadphaseProxy::isCompound(proxyType1))
+               {
+                       return m_swappedCompoundCreateFunc;
+               }
+       }
+
+       //failed to find an algorithm
+       return m_emptyCreateFunc;
+}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h
new file mode 100644 (file)
index 0000000..2e99f1d
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_DEFAULT_COLLISION_CONFIGURATION
+#define BT_DEFAULT_COLLISION_CONFIGURATION
+
+#include "btCollisionConfiguration.h"
+class btVoronoiSimplexSolver;
+class btGjkEpaPenetrationDepthSolver;
+
+
+///btCollisionConfiguration allows to configure Bullet collision detection
+///stack allocator, pool memory allocators
+///todo: describe the meaning
+class  btDefaultCollisionConfiguration : public btCollisionConfiguration
+{
+
+       int     m_persistentManifoldPoolSize;
+       
+       btStackAlloc*   m_stackAlloc;
+       bool    m_ownsStackAllocator;
+
+       btPoolAllocator*        m_persistentManifoldPool;
+       bool    m_ownsPersistentManifoldPool;
+
+       btPoolAllocator*        m_collisionAlgorithmPool;
+       bool    m_ownsCollisionAlgorithmPool;
+
+       //default simplex/penetration depth solvers
+       btVoronoiSimplexSolver* m_simplexSolver;
+       btGjkEpaPenetrationDepthSolver* m_pdSolver;
+       
+       //default CreationFunctions, filling the m_doubleDispatch table
+       btCollisionAlgorithmCreateFunc* m_convexConvexCreateFunc;
+       btCollisionAlgorithmCreateFunc* m_convexConcaveCreateFunc;
+       btCollisionAlgorithmCreateFunc* m_swappedConvexConcaveCreateFunc;
+       btCollisionAlgorithmCreateFunc* m_compoundCreateFunc;
+       btCollisionAlgorithmCreateFunc* m_swappedCompoundCreateFunc;
+       btCollisionAlgorithmCreateFunc* m_emptyCreateFunc;
+       btCollisionAlgorithmCreateFunc* m_sphereSphereCF;
+       btCollisionAlgorithmCreateFunc* m_sphereBoxCF;
+       btCollisionAlgorithmCreateFunc* m_boxSphereCF;
+       btCollisionAlgorithmCreateFunc* m_sphereTriangleCF;
+       btCollisionAlgorithmCreateFunc* m_triangleSphereCF;
+
+public:
+
+       btDefaultCollisionConfiguration(btStackAlloc*   stackAlloc=0,btPoolAllocator*   persistentManifoldPool=0,btPoolAllocator*       collisionAlgorithmPool=0);
+
+       virtual ~btDefaultCollisionConfiguration();
+
+               ///memory pools
+       virtual btPoolAllocator* getPersistentManifoldPool()
+       {
+               return m_persistentManifoldPool;
+       }
+
+       virtual btPoolAllocator* getCollisionAlgorithmPool()
+       {
+               return m_collisionAlgorithmPool;
+       }
+
+       virtual btStackAlloc*   getStackAllocator()
+       {
+               return m_stackAlloc;
+       }
+
+
+       btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1);
+
+
+};
+
+#endif //BT_DEFAULT_COLLISION_CONFIGURATION
+
index b1a193d2cfda47ab40733c03278db1035397ab47..89e7080780c427f7eae0ee87d46ca146688717d4 100644 (file)
@@ -15,8 +15,9 @@ subject to the following restrictions:
 
 #ifndef EMPTY_ALGORITH
 #define EMPTY_ALGORITH
-#include "../BroadphaseCollision/btCollisionAlgorithm.h"
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
 #include "btCollisionCreateFunc.h"
+#include "btCollisionDispatcher.h"
 
 #define ATTRIBUTE_ALIGNED(a)
 
@@ -39,7 +40,8 @@ public:
                {
                        (void)body0;
                        (void)body1;
-                       return new btEmptyAlgorithm(ci);
+                       void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btEmptyAlgorithm));
+                       return new(mem) btEmptyAlgorithm(ci);
                }
        };
 
index 490acc0b611c882b7bc0cc83ad48bd5030a5f417..61c4c231da4b2794491cbdc83d731e972b9311c9 100644 (file)
@@ -79,12 +79,25 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b
        }
 
        btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
-
+       newPt.m_positionWorldOnA = pointA;
+       newPt.m_positionWorldOnB = pointInWorld;
+       
        int insertIndex = m_manifoldPtr->getCacheEntry(newPt);
 
        newPt.m_combinedFriction = calculateCombinedFriction(m_body0,m_body1);
        newPt.m_combinedRestitution = calculateCombinedRestitution(m_body0,m_body1);
 
+       
+       ///todo, check this for any side effects
+       if (insertIndex >= 0)
+       {
+               //const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex);
+               m_manifoldPtr->replaceContactPoint(newPt,insertIndex);
+       } else
+       {
+               m_manifoldPtr->AddManifoldPoint(newPt);
+       }
+
        //User can override friction and/or restitution
        if (gContactAddedCallback &&
                //and if either of the two bodies requires custom material
@@ -97,13 +110,5 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b
                (*gContactAddedCallback)(newPt,obj0,m_partId0,m_index0,obj1,m_partId1,m_index1);
        }
 
-       if (insertIndex >= 0)
-       {
-               //const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex);
-               m_manifoldPtr->replaceContactPoint(newPt,insertIndex);
-       } else
-       {
-               m_manifoldPtr->AddManifoldPoint(newPt);
-       }
 }
 
index 77192625513880367269919ad88f9337969eb060..5aac9a46f6a9c9856a998dcbcae9b2aeb8fa6ae1 100644 (file)
@@ -18,12 +18,12 @@ subject to the following restrictions:
 #define MANIFOLD_RESULT_H
 
 class btCollisionObject;
-class btPersistentManifold;
+#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
 class btManifoldPoint;
 
 #include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
 
-#include "../../LinearMath/btTransform.h"
+#include "LinearMath/btTransform.h"
 
 typedef bool (*ContactAddedCallback)(btManifoldPoint& cp,      const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1);
 extern ContactAddedCallback            gContactAddedCallback;
@@ -60,6 +60,15 @@ public:
                m_manifoldPtr = manifoldPtr;
        }
 
+       const btPersistentManifold*     getPersistentManifold() const
+       {
+               return m_manifoldPtr;
+       }
+       btPersistentManifold*   getPersistentManifold()
+       {
+               return m_manifoldPtr;
+       }
+
        virtual void setShapeIdentifiers(int partId0,int index0,        int partId1,int index1)
        {
                        m_partId0=partId0;
@@ -70,6 +79,22 @@ public:
 
        virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth);
 
+       SIMD_FORCE_INLINE       void refreshContactPoints()
+       {
+               btAssert(m_manifoldPtr);
+               if (!m_manifoldPtr->getNumContacts())
+                       return;
+
+               bool isSwapped = m_manifoldPtr->getBody0() != m_body0;
+
+               if (isSwapped)
+               {
+                       m_manifoldPtr->refreshContactPoints(m_rootTransB,m_rootTransA);
+               } else
+               {
+                       m_manifoldPtr->refreshContactPoints(m_rootTransA,m_rootTransB);
+               }
+       }
 
 
 };
index ac2e8554c3a970b856e336b24e69559232194db3..6c42d1706ff147acf55815276adc41c38e6c6723 100644 (file)
@@ -25,17 +25,17 @@ void btSimulationIslandManager::initUnionFind(int n)
 }
                
 
-void btSimulationIslandManager::findUnions(btDispatcher* dispatcher)
+void btSimulationIslandManager::findUnions(btDispatcher* dispatcher,btCollisionWorld* colWorld)
 {
        
        {
-               for (int i=0;i<dispatcher->getNumManifolds();i++)
-               {
-                       const btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i);
-                       //static objects (invmass btScalar(0.)) don't merge !
+               btBroadphasePair* pairPtr = colWorld->getPairCache()->getOverlappingPairArrayPtr();
 
-                        const  btCollisionObject* colObj0 = static_cast<const btCollisionObject*>(manifold->getBody0());
-                        const  btCollisionObject* colObj1 = static_cast<const btCollisionObject*>(manifold->getBody1());
+               for (int i=0;i<colWorld->getPairCache()->getNumOverlappingPairs();i++)
+               {
+                       const btBroadphasePair& collisionPair = pairPtr[i];
+                       btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
+                       btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
 
                        if (((colObj0) && ((colObj0)->mergesSimulationIslands())) &&
                                ((colObj1) && ((colObj1)->mergesSimulationIslands())))
@@ -71,7 +71,7 @@ void  btSimulationIslandManager::updateActivationState(btCollisionWorld* colWorld
        }
        // do the union find
        
-       findUnions(dispatcher);
+       findUnions(dispatcher,colWorld);
        
 
        
@@ -138,19 +138,6 @@ class btPersistentManifoldSortPredicate
 void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback)
 {
 
-       
-       
-       /*if (0)
-       {
-               int maxNumManifolds = dispatcher->getNumManifolds();
-               btCollisionDispatcher* colDis = (btCollisionDispatcher*)dispatcher;
-               btPersistentManifold** manifold = colDis->getInternalManifoldPointer();
-               callback->ProcessIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, 0);
-               return;
-       }
-       */
-
-
        BEGIN_PROFILE("islandUnionFindAndHeapSort");
        
        //we are going to sort the unionfind array, and store the element id in the size
@@ -247,11 +234,17 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
                }
        }
 
-       btAlignedObjectArray<btPersistentManifold*>  islandmanifold;
+       
        int i;
        int maxNumManifolds = dispatcher->getNumManifolds();
-       islandmanifold.reserve(maxNumManifolds);
 
+#define SPLIT_ISLANDS 1
+#ifdef SPLIT_ISLANDS
+
+       
+#endif //SPLIT_ISLANDS
+
+       
        for (i=0;i<maxNumManifolds ;i++)
        {
                 btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i);
@@ -265,29 +258,35 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
                {
                
                        //kinematic objects don't merge islands, but wake up all connected objects
-                       if (colObj0->isStaticOrKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING)
+                       if (colObj0->isKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING)
                        {
                                colObj1->activate();
                        }
-                       if (colObj1->isStaticOrKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING)
+                       if (colObj1->isKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING)
                        {
                                colObj0->activate();
                        }
-
-                       //filtering for response
+#ifdef SPLIT_ISLANDS
+       //              //filtering for response
                        if (dispatcher->needsResponse(colObj0,colObj1))
-                               islandmanifold.push_back(manifold);
+                               m_islandmanifold.push_back(manifold);
+#endif //SPLIT_ISLANDS
                }
        }
 
-       int numManifolds = int (islandmanifold.size());
-
+#ifndef SPLIT_ISLANDS
+       btPersistentManifold** manifold = dispatcher->getInternalManifoldPointer();
+       
+       callback->ProcessIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, -1);
+#else
        // Sort manifolds, based on islands
        // Sort the vector using predicate and std::sort
        //std::sort(islandmanifold.begin(), islandmanifold.end(), btPersistentManifoldSortPredicate);
 
+       int numManifolds = int (m_islandmanifold.size());
+
        //we should do radix sort, it it much faster (O(n) instead of O (n log2(n))
-       islandmanifold.heapSort(btPersistentManifoldSortPredicate());
+       m_islandmanifold.heapSort(btPersistentManifoldSortPredicate());
 
        //now process all active islands (sets of manifolds for now)
 
@@ -298,8 +297,9 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
 
        END_PROFILE("islandUnionFindAndHeapSort");
 
-       btAlignedObjectArray<btCollisionObject*>        islandBodies;
+       
 
+//     printf("Start Islands\n");
 
        //traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated
        for ( startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
@@ -313,7 +313,7 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
                 {
                         int i = getUnionFind().getElement(endIslandIndex).m_sz;
                         btCollisionObject* colObj0 = collisionObjects[i];
-                                               islandBodies.push_back(colObj0);
+                                               m_islandBodies.push_back(colObj0);
                         if (!colObj0->isActive())
                                 islandSleeping = true;
                 }
@@ -325,12 +325,12 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
 
                if (startManifoldIndex<numManifolds)
                {
-                       int curIslandId = getIslandId(islandmanifold[startManifoldIndex]);
+                       int curIslandId = getIslandId(m_islandmanifold[startManifoldIndex]);
                        if (curIslandId == islandId)
                        {
-                               startManifold = &islandmanifold[startManifoldIndex];
+                               startManifold = &m_islandmanifold[startManifoldIndex];
                        
-                               for (endManifoldIndex = startManifoldIndex+1;(endManifoldIndex<numManifolds) && (islandId == getIslandId(islandmanifold[endManifoldIndex]));endManifoldIndex++)
+                               for (endManifoldIndex = startManifoldIndex+1;(endManifoldIndex<numManifolds) && (islandId == getIslandId(m_islandmanifold[endManifoldIndex]));endManifoldIndex++)
                                {
 
                                }
@@ -342,7 +342,8 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
 
                if (!islandSleeping)
                {
-                       callback->ProcessIsland(&islandBodies[0],islandBodies.size(),startManifold,numIslandManifolds, islandId);
+                       callback->ProcessIsland(&m_islandBodies[0],m_islandBodies.size(),startManifold,numIslandManifolds, islandId);
+//                     printf("Island callback of size:%d bodies, %d manifolds\n",islandBodies.size(),numIslandManifolds);
                }
                
                if (numIslandManifolds)
@@ -350,8 +351,9 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
                        startManifoldIndex = endManifoldIndex;
                }
 
-               islandBodies.resize(0);
+               m_islandBodies.resize(0);
        }
+#endif //SPLIT_ISLANDS
 
-       
+       m_islandmanifold.resize(0);
 }
index d91ed1c20eb276b8fb1f26e3d82f76ac52988bc5..01a059b5fbefe068758e04d414b50d6c2112d9fa 100644 (file)
@@ -16,18 +16,26 @@ subject to the following restrictions:
 #ifndef SIMULATION_ISLAND_MANAGER_H
 #define SIMULATION_ISLAND_MANAGER_H
 
-#include "../CollisionDispatch/btUnionFind.h"
+#include "BulletCollision/CollisionDispatch/btUnionFind.h"
 #include "btCollisionCreateFunc.h"
+#include "LinearMath/btAlignedObjectArray.h"
+
 
 class btCollisionObject;
 class btCollisionWorld;
 class btDispatcher;
+class btPersistentManifold;
+
 
 ///SimulationIslandManager creates and handles simulation islands, using btUnionFind
 class btSimulationIslandManager
 {
        btUnionFind m_unionFind;
 
+       btAlignedObjectArray<btPersistentManifold*>  m_islandmanifold;
+       btAlignedObjectArray<btCollisionObject* >  m_islandBodies;
+       
+       
 public:
        btSimulationIslandManager();
        virtual ~btSimulationIslandManager();
@@ -42,7 +50,7 @@ public:
        virtual void    storeIslandActivationState(btCollisionWorld* world);
 
 
-       void    findUnions(btDispatcher* dispatcher);
+       void    findUnions(btDispatcher* dispatcher,btCollisionWorld* colWorld);
 
        
 
index 05556bd34e29ada4a3b06c20afbf5381f60b1eb6..1e4bbce451ddc4b21c04e31176a5c72d1ebdad60 100644 (file)
@@ -68,18 +68,25 @@ void btSphereBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,b
        
        btScalar dist = getSphereDistance(boxObj,pOnBox,pOnSphere,sphereCenter,radius);
 
+       resultOut->setPersistentManifold(m_manifoldPtr);
+
        if (dist < SIMD_EPSILON)
        {
                btVector3 normalOnSurfaceB = (pOnBox- pOnSphere).normalize();
 
                /// report a contact. internally this will be kept persistent, and contact reduction is done
 
-               resultOut->setPersistentManifold(m_manifoldPtr);
                resultOut->addContactPoint(normalOnSurfaceB,pOnBox,dist);
                
        }
 
-       
+       if (m_ownManifold)
+       {
+               if (m_manifoldPtr->getNumContacts())
+               {
+                       resultOut->refreshContactPoints();
+               }
+       }
 
 }
 
@@ -102,8 +109,8 @@ btScalar btSphereBoxCollisionAlgorithm::getSphereDistance(btCollisionObject* box
        btVector3 bounds[2];
        btBoxShape* boxShape= (btBoxShape*)boxObj->getCollisionShape();
        
-       bounds[0] = -boxShape->getHalfExtents();
-       bounds[1] = boxShape->getHalfExtents();
+       bounds[0] = -boxShape->getHalfExtentsWithoutMargin();
+       bounds[1] = boxShape->getHalfExtentsWithoutMargin();
 
        margins = boxShape->getMargin();//also add sphereShape margin?
 
@@ -209,6 +216,10 @@ btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btCollisionObject*
        btVector3       p0, tmp, prel, n[6], normal;
        btScalar   fSep = btScalar(-10000000.0), fSepThis;
 
+       // set p0 and normal to a default value to shup up GCC
+       p0.setValue(btScalar(0.), btScalar(0.), btScalar(0.));
+       normal.setValue(btScalar(0.), btScalar(0.), btScalar(0.));
+
        n[0].setValue( btScalar(-1.0),  btScalar(0.0),  btScalar(0.0) );
        n[1].setValue(  btScalar(0.0), btScalar(-1.0),  btScalar(0.0) );
        n[2].setValue(  btScalar(0.0),  btScalar(0.0), btScalar(-1.0) );
index 07592909200e588ffca7404c968ab5545245a382..b839dc4adb129b141252b03a489f86a820d9eb98 100644 (file)
@@ -16,11 +16,13 @@ subject to the following restrictions:
 #ifndef SPHERE_BOX_COLLISION_ALGORITHM_H
 #define SPHERE_BOX_COLLISION_ALGORITHM_H
 
-#include "../BroadphaseCollision/btCollisionAlgorithm.h"
-#include "../BroadphaseCollision/btBroadphaseProxy.h"
-#include "../CollisionDispatch/btCollisionCreateFunc.h"
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
 class btPersistentManifold;
-#include "../../LinearMath/btVector3.h"
+#include "btCollisionDispatcher.h"
+
+#include "LinearMath/btVector3.h"
 
 /// btSphereBoxCollisionAlgorithm  provides sphere-box collision detection.
 /// Other features are frame-coherency (persistent data) and collision response.
@@ -48,12 +50,13 @@ public:
        {
                virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
                {
+                       void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereBoxCollisionAlgorithm));
                        if (!m_swapped)
                        {
-                               return new btSphereBoxCollisionAlgorithm(0,ci,body0,body1,false);
+                               return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0,body1,false);
                        } else
                        {
-                               return new btSphereBoxCollisionAlgorithm(0,ci,body0,body1,true);
+                               return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0,body1,true);
                        }
                }
        };
index 424ff432f845dcdfb896ad520555ed2bda56775d..e7f42647e61dccb3c84be249fe915508905aee03 100644 (file)
@@ -46,6 +46,8 @@ void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0
        if (!m_manifoldPtr)
                return;
 
+       resultOut->setPersistentManifold(m_manifoldPtr);
+
        btSphereShape* sphere0 = (btSphereShape*)col0->getCollisionShape();
        btSphereShape* sphere1 = (btSphereShape*)col1->getCollisionShape();
 
@@ -54,10 +56,13 @@ void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0
        btScalar radius0 = sphere0->getRadius();
        btScalar radius1 = sphere1->getRadius();
 
+       m_manifoldPtr->clearManifold();
+
        ///iff distance positive, don't generate a new contact
        if ( len > (radius0+radius1))
+       {
                return;
-
+       }
        ///distance (negative means penetration)
        btScalar dist = len - (radius0+radius1);
 
@@ -68,9 +73,12 @@ void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0
        btVector3 pos1 = col1->getWorldTransform().getOrigin() + radius1* normalOnSurfaceB;
 
        /// report a contact. internally this will be kept persistent, and contact reduction is done
-       resultOut->setPersistentManifold(m_manifoldPtr);
+       
+       
        resultOut->addContactPoint(normalOnSurfaceB,pos1,dist);
 
+       //no resultOut->refreshContactPoints(); needed, because of clearManifold (all points are new)
+
 }
 
 btScalar btSphereSphereCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
index 7a19ff31edfb899cfa06c7c88e6acdce527e10f7..bcaa0d303a90f5d3025fc694de9c7170b125d5d8 100644 (file)
@@ -16,9 +16,11 @@ subject to the following restrictions:
 #ifndef SPHERE_SPHERE_COLLISION_ALGORITHM_H
 #define SPHERE_SPHERE_COLLISION_ALGORITHM_H
 
-#include "../BroadphaseCollision/btCollisionAlgorithm.h"
-#include "../BroadphaseCollision/btBroadphaseProxy.h"
-#include "../CollisionDispatch/btCollisionCreateFunc.h"
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
+#include "btCollisionDispatcher.h"
+
 class btPersistentManifold;
 
 /// btSphereSphereCollisionAlgorithm  provides sphere-sphere collision detection.
@@ -46,7 +48,8 @@ public:
        {
                virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
                {
-                       return new btSphereSphereCollisionAlgorithm(0,ci,body0,body1);
+                       void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereSphereCollisionAlgorithm));
+                       return new(mem) btSphereSphereCollisionAlgorithm(0,ci,body0,body1);
                }
        };
 
index b011b707e3f5cf7a7efb076abbb27f2a251a4ce8..5d50bfed7a1dbf9e5ab058d66f659e97ef304e03 100644 (file)
@@ -48,8 +48,11 @@ void btSphereTriangleCollisionAlgorithm::processCollision (btCollisionObject* co
        if (!m_manifoldPtr)
                return;
 
-       btSphereShape* sphere = (btSphereShape*)col0->getCollisionShape();
-       btTriangleShape* triangle = (btTriangleShape*)col1->getCollisionShape();
+       btCollisionObject* sphereObj = m_swapped? col1 : col0;
+       btCollisionObject* triObj = m_swapped? col0 : col1;
+
+       btSphereShape* sphere = (btSphereShape*)sphereObj->getCollisionShape();
+       btTriangleShape* triangle = (btTriangleShape*)triObj->getCollisionShape();
        
        /// report a contact. internally this will be kept persistent, and contact reduction is done
        resultOut->setPersistentManifold(m_manifoldPtr);
@@ -62,6 +65,9 @@ void btSphereTriangleCollisionAlgorithm::processCollision (btCollisionObject* co
 
        detector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
 
+       if (m_ownManifold)
+               resultOut->refreshContactPoints();
+       
 }
 
 btScalar btSphereTriangleCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
index 57c6e6af6191b1a799662324ad0aadfb0daba62d..4aefc0c43a5de7303a6ad61820228e1134c608d6 100644 (file)
@@ -16,10 +16,11 @@ subject to the following restrictions:
 #ifndef SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
 #define SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
 
-#include "../BroadphaseCollision/btCollisionAlgorithm.h"
-#include "../BroadphaseCollision/btBroadphaseProxy.h"
-#include "../CollisionDispatch/btCollisionCreateFunc.h"
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
 class btPersistentManifold;
+#include "btCollisionDispatcher.h"
 
 /// btSphereSphereCollisionAlgorithm  provides sphere-sphere collision detection.
 /// Other features are frame-coherency (persistent data) and collision response.
@@ -49,7 +50,9 @@ public:
                virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
                {
                        
-                               return new btSphereTriangleCollisionAlgorithm(ci.m_manifold,ci,body0,body1,m_swapped);
+                       void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereTriangleCollisionAlgorithm));
+
+                       return new(mem) btSphereTriangleCollisionAlgorithm(ci.m_manifold,ci,body0,body1,m_swapped);
                }
        };
 
index 6225433579691f12594136b0d5ddf5982ee6177d..c81be8aa75c8a52c34c9d6db9137a13870e12e16 100644 (file)
@@ -18,6 +18,7 @@ subject to the following restrictions:
 
 
 
+
 btUnionFind::~btUnionFind()
 {
        Free();
index 236cc33b94f8fbc1eb814eba6fc25b4dcfc77db0..820c8bc858e5ef95f52d80785b5e768868164fb4 100644 (file)
@@ -16,7 +16,7 @@ subject to the following restrictions:
 #ifndef UNION_FIND_H
 #define UNION_FIND_H
 
-#include "../../LinearMath/btAlignedObjectArray.h"
+#include "LinearMath/btAlignedObjectArray.h"
 
        #define USE_PATH_COMPRESSION 1
 
@@ -46,11 +46,11 @@ class btUnionFind
 
          void  reset(int N);
 
-         inline int    getNumElements() const
+         SIMD_FORCE_INLINE int getNumElements() const
          {
                  return int(m_elements.size());
          }
-         inline bool  isRoot(int x) const
+         SIMD_FORCE_INLINE bool  isRoot(int x) const
          {
                  return (x == m_elements[x].m_id);
          }
index 636b0046c13893f0c45cae6bff0ec4d403c48308..adac455bbcb2a92de128f7d8701405d0a4a2692f 100644 (file)
@@ -15,16 +15,13 @@ subject to the following restrictions:
 
 #include "btBoxShape.h"
 
-btVector3 btBoxShape::getHalfExtents() const
-{
-       return m_implicitShapeDimensions * m_localScaling;
-}
+
 //{ 
 
 
 void btBoxShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
 {
-       btVector3 halfExtents = getHalfExtents();
+       const btVector3& halfExtents = getHalfExtentsWithoutMargin();
 
        btMatrix3x3 abs_b = t.getBasis().absolute();  
        btPoint3 center = t.getOrigin();
@@ -40,10 +37,10 @@ void btBoxShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabb
 }
 
 
-void   btBoxShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
+void   btBoxShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
 {
        //btScalar margin = btScalar(0.);
-       btVector3 halfExtents = getHalfExtents();
+       btVector3 halfExtents = getHalfExtentsWithMargin();
 
        btScalar lx=btScalar(2.)*(halfExtents.x());
        btScalar ly=btScalar(2.)*(halfExtents.y());
index bc42f146c7c5ac08ca033fdc1e54bdfca6bd4173..98f1bd34b09fc0e2c224d7b7feb74c4761bb9afa 100644 (file)
@@ -18,9 +18,9 @@ subject to the following restrictions:
 
 #include "btPolyhedralConvexShape.h"
 #include "btCollisionMargin.h"
-#include "../BroadphaseCollision/btBroadphaseProxy.h"
-#include "../../LinearMath/btPoint3.h"
-#include "../../LinearMath/btSimdMinMax.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "LinearMath/btPoint3.h"
+#include "LinearMath/btMinMax.h"
 
 ///btBoxShape implements both a feature based (vertex/edge/plane) and implicit (getSupportingVertex) Box
 class btBoxShape: public btPolyhedralConvexShape
@@ -31,47 +31,52 @@ class btBoxShape: public btPolyhedralConvexShape
 
 public:
 
-       btVector3 getHalfExtents() const;
-               
+       btVector3 getHalfExtentsWithMargin() const
+       {
+               btVector3 halfExtents = getHalfExtentsWithoutMargin();
+               btVector3 margin(getMargin(),getMargin(),getMargin());
+               halfExtents += margin;
+               return halfExtents;
+       }
+       
+       const btVector3& getHalfExtentsWithoutMargin() const
+       {
+               return m_implicitShapeDimensions;//changed in Bullet 2.63: assume the scaling and margin are included
+       }
+       
+
        virtual int     getShapeType() const { return BOX_SHAPE_PROXYTYPE;}
 
        virtual btVector3       localGetSupportingVertex(const btVector3& vec) const
        {
+               btVector3 halfExtents = getHalfExtentsWithoutMargin();
+               btVector3 margin(getMargin(),getMargin(),getMargin());
+               halfExtents += margin;
                
-               btVector3 halfExtents = getHalfExtents();
-               
-               btVector3 supVertex;
-               supVertex = btPoint3(vec.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(),
-                     vec.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(),
-                     vec.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z()); 
-  
-               return supVertex;
+               return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
+                       btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
+                       btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
        }
 
-       virtual inline btVector3        localGetSupportingVertexWithoutMargin(const btVector3& vec)const
+       SIMD_FORCE_INLINE  btVector3    localGetSupportingVertexWithoutMargin(const btVector3& vec)const
        {
-               btVector3 halfExtents = getHalfExtents();
-               btVector3 margin(getMargin(),getMargin(),getMargin());
-               halfExtents -= margin;
-
-               return btVector3(vec.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(),
-                    vec.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(),
-                    vec.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z()); 
+               const btVector3& halfExtents = getHalfExtentsWithoutMargin();
+               
+               return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
+                       btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
+                       btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
        }
 
        virtual void    batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
        {
-               btVector3 halfExtents = getHalfExtents();
-               btVector3 margin(getMargin(),getMargin(),getMargin());
-               halfExtents -= margin;
-
-
+               const btVector3& halfExtents = getHalfExtentsWithoutMargin();
+       
                for (int i=0;i<numVectors;i++)
                {
                        const btVector3& vec = vectors[i];
-                       supportVerticesOut[i].setValue(vec.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(),
-                    vec.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(),
-                    vec.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z()); 
+                       supportVerticesOut[i].setValue(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
+                               btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
+                               btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); 
                }
 
        }
@@ -79,14 +84,38 @@ public:
 
        btBoxShape( const btVector3& boxHalfExtents)
        {
-               m_implicitShapeDimensions = boxHalfExtents;
+               btVector3 margin(getMargin(),getMargin(),getMargin());
+               m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin;
        };
-       
+
+       virtual void setMargin(btScalar collisionMargin)
+       {
+               //correct the m_implicitShapeDimensions for the margin
+               btVector3 oldMargin(getMargin(),getMargin(),getMargin());
+               btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
+               
+               btConvexInternalShape::setMargin(collisionMargin);
+               btVector3 newMargin(getMargin(),getMargin(),getMargin());
+               m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin;
+
+       }
+       virtual void    setLocalScaling(const btVector3& scaling)
+       {
+               btVector3 oldMargin(getMargin(),getMargin(),getMargin());
+               btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
+               btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling;
+
+               btConvexInternalShape::setLocalScaling(scaling);
+
+               m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin;
+
+       }
+
        virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
 
        
 
-       virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia);
+       virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia) const;
 
        virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const
        {
@@ -116,7 +145,7 @@ public:
 
        virtual void getVertex(int i,btVector3& vtx) const
        {
-               btVector3 halfExtents = getHalfExtents();
+               btVector3 halfExtents = getHalfExtentsWithoutMargin();
 
                vtx = btVector3(
                                halfExtents.x() * (1-(i&1)) - halfExtents.x() * (i&1),
@@ -127,7 +156,7 @@ public:
 
        virtual void    getPlaneEquation(btVector4& plane,int i) const
        {
-               btVector3 halfExtents = getHalfExtents();
+               btVector3 halfExtents = getHalfExtentsWithoutMargin();
 
                switch (i)
                {
@@ -234,7 +263,7 @@ public:
        
        virtual bool isInside(const btPoint3& pt,btScalar tolerance) const
        {
-               btVector3 halfExtents = getHalfExtents();
+               btVector3 halfExtents = getHalfExtentsWithoutMargin();
 
                //btScalar minDist = 2*tolerance;
                
@@ -250,7 +279,7 @@ public:
 
 
        //debugging
-       virtual char*   getName()const
+       virtual const char*     getName()const
        {
                return "Box";
        }
@@ -291,3 +320,4 @@ public:
 
 #endif //OBB_BOX_MINKOWSKI_H
 
+
index 8da554ef14d02d7dd5f1161d30a2f2074760ca4f..eea263fe5b410593562fe32b59e3fcb365809ac7 100644 (file)
@@ -21,29 +21,47 @@ subject to the following restrictions:
 
 ///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization.
 ///Uses an interface to access the triangles to allow for sharing graphics/physics triangles.
-btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression)
-:btTriangleMeshShape(meshInterface),m_useQuantizedAabbCompression(useQuantizedAabbCompression)
+btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh)
+:btTriangleMeshShape(meshInterface),
+m_bvh(0),
+m_useQuantizedAabbCompression(useQuantizedAabbCompression),
+m_ownsBvh(false)
 {
        //construct bvh from meshInterface
 #ifndef DISABLE_BVH
 
-       m_bvh = new btOptimizedBvh();
        btVector3 bvhAabbMin,bvhAabbMax;
        meshInterface->calculateAabbBruteForce(bvhAabbMin,bvhAabbMax);
-       m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
+       
+       if (buildBvh)
+       {
+               void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
+               m_bvh = new (mem) btOptimizedBvh();
+               m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
+               m_ownsBvh = true;
+       }
 
 #endif //DISABLE_BVH
 
 }
 
-btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax)
-:btTriangleMeshShape(meshInterface),m_useQuantizedAabbCompression(useQuantizedAabbCompression)
+btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,bool buildBvh)
+:btTriangleMeshShape(meshInterface),
+m_bvh(0),
+m_useQuantizedAabbCompression(useQuantizedAabbCompression),
+m_ownsBvh(false)
 {
        //construct bvh from meshInterface
 #ifndef DISABLE_BVH
 
-       m_bvh = new btOptimizedBvh();
-       m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
+       if (buildBvh)
+       {
+               void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
+               m_bvh = new (mem) btOptimizedBvh();
+               
+               m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
+               m_ownsBvh = true;
+       }
 
 #endif //DISABLE_BVH
 
@@ -67,7 +85,11 @@ void btBvhTriangleMeshShape::refitTree()
 
 btBvhTriangleMeshShape::~btBvhTriangleMeshShape()
 {
-       delete m_bvh;
+       if (m_ownsBvh)
+       {
+               m_bvh->~btOptimizedBvh();
+               btAlignedFree(m_bvh);
+       }
 }
 
 //perform bvh tree traversal and report overlapping triangles to 'callback'
@@ -163,9 +185,14 @@ void       btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling)
        if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON)
        {
                btTriangleMeshShape::setLocalScaling(scaling);
-               delete m_bvh;
+               if (m_ownsBvh)
+               {
+                       m_bvh->~btOptimizedBvh();
+                       btAlignedFree(m_bvh);
+               }
                ///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();
+               void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
+               m_bvh = new(mem) btOptimizedBvh();
                //rebuild the bvh...
                m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax);
 
index 4914d9f959c6a775e94968ae62991333c8b429cc..95c73b2441f1f2ad9f0ddb964286a641ff371da9 100644 (file)
@@ -18,6 +18,7 @@ subject to the following restrictions:
 
 #include "btTriangleMeshShape.h"
 #include "btOptimizedBvh.h"
+#include "LinearMath/btAlignedAllocator.h"
 
 ///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization.
 ///Uses an interface to access the triangles to allow for sharing graphics/physics triangles.
@@ -26,15 +27,18 @@ ATTRIBUTE_ALIGNED16(class) btBvhTriangleMeshShape : public btTriangleMeshShape
 
        btOptimizedBvh* m_bvh;
        bool m_useQuantizedAabbCompression;
-       bool m_pad[12];////need padding due to alignment
+       bool    m_ownsBvh;
+       bool m_pad[11];////need padding due to alignment
 
 public:
 
-       btBvhTriangleMeshShape() :btTriangleMeshShape(0) {};
-       btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression);
+       BT_DECLARE_ALIGNED_ALLOCATOR();
+
+       btBvhTriangleMeshShape() :btTriangleMeshShape(0),m_bvh(0),m_ownsBvh(false) {};
+       btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true);
 
        ///optionally pass in a larger bvh aabb, used for quantization. This allows for deformations within this aabb
-       btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax);
+       btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax, bool buildBvh = true);
        
        virtual ~btBvhTriangleMeshShape();
 
@@ -56,7 +60,7 @@ public:
        void    partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax);
 
        //debugging
-       virtual char*   getName()const {return "BVHTRIANGLEMESH";}
+       virtual const char*     getName()const {return "BVHTRIANGLEMESH";}
 
 
        virtual void    setLocalScaling(const btVector3& scaling);
@@ -65,6 +69,17 @@ public:
        {
                return m_bvh;
        }
+
+
+       void    setOptimizedBvh(btOptimizedBvh* bvh)
+       {
+               btAssert(!m_bvh);
+               btAssert(!m_ownsBvh);
+
+               m_bvh = bvh;
+               m_ownsBvh = false;
+       }
+
        bool    usesQuantizedAabbCompression() const
        {
                return  m_useQuantizedAabbCompression;
index b7e15172da2c701b4e793308f4632f6a70a4add8..b4f21f38b3d62228d5a393d33434297df2982f7f 100644 (file)
@@ -112,7 +112,7 @@ btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height)
 }
 
 
-void   btCapsuleShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
+void   btCapsuleShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
 {
        //as an approximation, take the inertia of the box that bounds the spheres
 
index 27da8adefa5d22113e03be1b25921e0ea0b3ce58..0b566450fef22e395d533121de1072bee94dbe8d 100644 (file)
@@ -16,20 +16,20 @@ subject to the following restrictions:
 #ifndef BT_CAPSULE_SHAPE_H
 #define BT_CAPSULE_SHAPE_H
 
-#include "btConvexShape.h"
-#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
+#include "btConvexInternalShape.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
 
 
 ///btCapsuleShape represents a capsule around the Y axis
 ///A more general solution that can represent capsules is the btMultiSphereShape
-class btCapsuleShape : public btConvexShape
+class btCapsuleShape : public btConvexInternalShape
 {
 
 public:
        btCapsuleShape(btScalar radius,btScalar height);
 
        ///CollisionShape Interface
-       virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia);
+       virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia) const;
 
        /// btConvexShape Interface
        virtual btVector3       localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
@@ -38,7 +38,7 @@ public:
        
        virtual int     getShapeType() const { return CAPSULE_SHAPE_PROXYTYPE; }
 
-       virtual char*   getName()const 
+       virtual const char*     getName()const 
        {
                return "CapsuleShape";
        }
index 96268734a8384c26116dd0e0238a54407c2b94c0..53fb12e33a17459e907f73be96f475646ea89d8e 100644 (file)
@@ -16,11 +16,11 @@ subject to the following restrictions:
 #ifndef COLLISION_SHAPE_H
 #define COLLISION_SHAPE_H
 
-#include "../../LinearMath/btTransform.h"
-#include "../../LinearMath/btVector3.h"
-#include "../../LinearMath/btMatrix3x3.h"
-#include "../../LinearMath/btPoint3.h"
-#include "../BroadphaseCollision/btBroadphaseProxy.h" //for the shape types
+#include "LinearMath/btTransform.h"
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btMatrix3x3.h"
+#include "LinearMath/btPoint3.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" //for the shape types
 
 ///btCollisionShape provides interface for collision shapes that can be shared among btCollisionObjects.
 class btCollisionShape
@@ -49,26 +49,26 @@ public:
 
 #ifndef __SPU__
 
-       inline bool     isPolyhedral() const
+       SIMD_FORCE_INLINE bool  isPolyhedral() const
        {
                return btBroadphaseProxy::isPolyhedral(getShapeType());
        }
 
-       inline bool     isConvex() const
+       SIMD_FORCE_INLINE bool  isConvex() const
        {
                return btBroadphaseProxy::isConvex(getShapeType());
        }
-       inline bool     isConcave() const
+       SIMD_FORCE_INLINE bool  isConcave() const
        {
                return btBroadphaseProxy::isConcave(getShapeType());
        }
-       inline bool     isCompound() const
+       SIMD_FORCE_INLINE bool  isCompound() const
        {
                return btBroadphaseProxy::isCompound(getShapeType());
        }
 
        ///isInfinite is used to catch simulation error (aabb check)
-       inline bool isInfinite() const
+       SIMD_FORCE_INLINE bool isInfinite() const
        {
                return btBroadphaseProxy::isInfinite(getShapeType());
        }
@@ -76,11 +76,11 @@ public:
        virtual int             getShapeType() const=0;
        virtual void    setLocalScaling(const btVector3& scaling) =0;
        virtual const btVector3& getLocalScaling() const =0;
-       virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia) = 0;
+       virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia) const = 0;
 
 
 //debugging support
-       virtual char*   getName()const =0 ;
+       virtual const char*     getName()const =0 ;
 #endif //__SPU__
 
        
index a4712b3e9257fe6fdbc71fdf84abc68d7dbc1470..114a1f4c1fcc3a64eb20780091ad156cb806f82f 100644 (file)
@@ -35,8 +35,15 @@ btCompoundShape::~btCompoundShape()
 
 void   btCompoundShape::addChildShape(const btTransform& localTransform,btCollisionShape* shape)
 {
-       m_childTransforms.push_back(localTransform);
-       m_childShapes.push_back(shape);
+       //m_childTransforms.push_back(localTransform);
+       //m_childShapes.push_back(shape);
+       btCompoundShapeChild child;
+       child.m_transform = localTransform;
+       child.m_childShape = shape;
+       child.m_childShapeType = shape->getShapeType();
+       child.m_childMargin = shape->getMargin();
+
+       m_children.push_back(child);
 
        //extend the local aabbMin/aabbMax
        btVector3 localAabbMin,localAabbMax;
@@ -76,7 +83,7 @@ void btCompoundShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVect
        aabbMax = center + extent;
 }
 
-void   btCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
+void   btCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
 {
        //approximation: take the inertia from the aabb for now
        btTransform ident;
index 86dc1f809476147af89af70e3d8474396b5c13bb..d23bd65b5e8984d85f8c804c4e275820ff5562c3 100644 (file)
@@ -18,26 +18,39 @@ subject to the following restrictions:
 
 #include "btCollisionShape.h"
 
-#include "../../LinearMath/btVector3.h"
-#include "../../LinearMath/btTransform.h"
-#include "../../LinearMath/btMatrix3x3.h"
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btTransform.h"
+#include "LinearMath/btMatrix3x3.h"
 #include "btCollisionMargin.h"
-#include "../../LinearMath/btAlignedObjectArray.h"
+#include "LinearMath/btAlignedObjectArray.h"
 
 class btOptimizedBvh;
 
+ATTRIBUTE_ALIGNED16(struct) btCompoundShapeChild
+{
+       BT_DECLARE_ALIGNED_ALLOCATOR();
+
+       btTransform                     m_transform;
+       btCollisionShape*       m_childShape;
+       int                                     m_childShapeType;
+       btScalar                        m_childMargin;
+};
+       
 /// btCompoundShape allows to store multiple other btCollisionShapes
 /// This allows for concave collision objects. This is more general then the Static Concave btTriangleMeshShape.
-class btCompoundShape  : public btCollisionShape
+ATTRIBUTE_ALIGNED16(class) btCompoundShape     : public btCollisionShape
 {
-       btAlignedObjectArray<btTransform>               m_childTransforms;
-       btAlignedObjectArray<btCollisionShape*> m_childShapes;
+       //btAlignedObjectArray<btTransform>             m_childTransforms;
+       //btAlignedObjectArray<btCollisionShape*>       m_childShapes;
+       btAlignedObjectArray<btCompoundShapeChild> m_children;
        btVector3                                               m_localAabbMin;
        btVector3                                               m_localAabbMax;
 
        btOptimizedBvh*                                 m_aabbTree;
 
 public:
+       BT_DECLARE_ALIGNED_ALLOCATOR();
+
        btCompoundShape();
 
        virtual ~btCompoundShape();
@@ -46,25 +59,31 @@ public:
 
        int             getNumChildShapes() const
        {
-               return int (m_childShapes.size());
+               return int (m_children.size());
        }
 
        btCollisionShape* getChildShape(int index)
        {
-               return m_childShapes[index];
+               return m_children[index].m_childShape;
        }
        const btCollisionShape* getChildShape(int index) const
        {
-               return m_childShapes[index];
+               return m_children[index].m_childShape;
        }
 
-       btTransform&    getChildTransform(int index)
+       btTransform     getChildTransform(int index)
        {
-               return m_childTransforms[index];
+               return m_children[index].m_transform;
        }
-       const btTransform&      getChildTransform(int index) const
+       const btTransform       getChildTransform(int index) const
+       {
+               return m_children[index].m_transform;
+       }
+
+
+       btCompoundShapeChild* getChildList()
        {
-               return m_childTransforms[index];
+               return &m_children[0];
        }
 
        ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
@@ -80,7 +99,7 @@ public:
                return m_localScaling;
        }
 
-       virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia);
+       virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia) const;
        
        virtual int     getShapeType() const { return COMPOUND_SHAPE_PROXYTYPE;}
 
@@ -92,7 +111,7 @@ public:
        {
                return m_collisionMargin;
        }
-       virtual char*   getName()const
+       virtual const char*     getName()const
        {
                return "Compound";
        }
index 73f974e4ee9b55fb3250bbbdfa34309303b8663b..4db4e6513dd2be93e980d3203f9f04d33b78ca01 100644 (file)
@@ -17,7 +17,7 @@ subject to the following restrictions:
 #define CONCAVE_SHAPE_H
 
 #include "btCollisionShape.h"
-#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
 #include "btTriangleCallback.h"
 
 
index 3ccda5b12c68cf8e6b772f3906de1225d544de50..34f36b35f87af2d609e79ede9ef4a45fbd1ec8d4 100644 (file)
@@ -16,11 +16,11 @@ subject to the following restrictions:
 #ifndef CONE_MINKOWSKI_H
 #define CONE_MINKOWSKI_H
 
-#include "btConvexShape.h"
-#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
+#include "btConvexInternalShape.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
 
 ///btConeShape implements a Cone shape, around the Y axis
-class btConeShape : public btConvexShape
+class btConeShape : public btConvexInternalShape
 
 {
 
@@ -42,7 +42,7 @@ public:
        btScalar getHeight() const { return m_height;}
 
 
-       virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia)
+       virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia) const
        {
                btTransform identity;
                identity.setIdentity();
@@ -72,7 +72,7 @@ public:
 
                virtual int     getShapeType() const { return CONE_SHAPE_PROXYTYPE; }
 
-               virtual char*   getName()const 
+               virtual const char*     getName()const 
                {
                        return "Cone";
                }
index 3fd5e382525b24e626b59fb09a1eed43b380b915..0928d68b8fc72d290aab3b0c60c9f144d6a8b5d7 100644 (file)
@@ -17,8 +17,8 @@ subject to the following restrictions:
 #define CONVEX_HULL_SHAPE_H
 
 #include "btPolyhedralConvexShape.h"
-#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
-#include "../../LinearMath/btAlignedObjectArray.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
+#include "LinearMath/btAlignedObjectArray.h"
 
 ///ConvexHullShape implements an implicit (getSupportingVertex) Convex Hull of a Point Cloud (vertices)
 ///No connectivity is needed. localGetSupportingVertex iterates linearly though all vertices.
@@ -29,6 +29,7 @@ ATTRIBUTE_ALIGNED16(class) btConvexHullShape : public btPolyhedralConvexShape
        btAlignedObjectArray<btPoint3>  m_points;
 
 public:
+       BT_DECLARE_ALIGNED_ALLOCATOR();
 
        
        ///this constructor optionally takes in a pointer to points. Each point is assumed to be 3 consecutive btScalar (x,y,z), the striding defines the number of bytes between each point, in memory.
@@ -56,7 +57,7 @@ public:
        virtual int     getShapeType()const { return CONVEX_HULL_SHAPE_PROXYTYPE; }
 
        //debugging
-       virtual char*   getName()const {return "Convex";}
+       virtual const char*     getName()const {return "Convex";}
 
        
        virtual int     getNumVertices() const;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp
new file mode 100644 (file)
index 0000000..f828d28
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+#include "btConvexInternalShape.h"
+
+
+btConvexInternalShape::btConvexInternalShape()
+: m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),
+m_collisionMargin(CONVEX_DISTANCE_MARGIN)
+{
+}
+
+
+void   btConvexInternalShape::setLocalScaling(const btVector3& scaling)
+{
+       m_localScaling = scaling;
+}
+
+
+
+void   btConvexInternalShape::getAabbSlow(const btTransform& trans,btVector3&minAabb,btVector3&maxAabb) const
+{
+
+       btScalar margin = getMargin();
+