Upgraded to Bullet 2.74. The upgrade introduced a few bugs, which need to be fixed before Blender 2.49.
In particular, the Bullet vehicle seems broken, and some soft-body demos don't work. No new features or benefits are added yet, but a few improvements are planned before Blender 2.49 release. Please update the build systems, and add those 3 files: extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp extern/bullet2/src/BulletCollision/CollisionDispatch/btGhostObject.cpp extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp I'll watch the Blender mailing list, in case this commit causes some issues.
This commit is contained in:
parent
f8ef887880
commit
982a5cc60d
18
extern/bullet2/src/Bullet-C-Api.h
vendored
18
extern/bullet2/src/Bullet-C-Api.h
vendored
@ -38,37 +38,37 @@ typedef plReal plQuaternion[4];
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Particular physics SDK */
|
||||
/** Particular physics SDK (C-API) */
|
||||
PL_DECLARE_HANDLE(plPhysicsSdkHandle);
|
||||
|
||||
/* Dynamics world, belonging to some physics SDK */
|
||||
/** Dynamics world, belonging to some physics SDK (C-API)*/
|
||||
PL_DECLARE_HANDLE(plDynamicsWorldHandle);
|
||||
|
||||
/* Rigid Body that can be part of a Dynamics World */
|
||||
/** Rigid Body that can be part of a Dynamics World (C-API)*/
|
||||
PL_DECLARE_HANDLE(plRigidBodyHandle);
|
||||
|
||||
/* Collision Shape/Geometry, property of a Rigid Body */
|
||||
/** Collision Shape/Geometry, property of a Rigid Body (C-API)*/
|
||||
PL_DECLARE_HANDLE(plCollisionShapeHandle);
|
||||
|
||||
/* Constraint for Rigid Bodies */
|
||||
/** Constraint for Rigid Bodies (C-API)*/
|
||||
PL_DECLARE_HANDLE(plConstraintHandle);
|
||||
|
||||
/* Triangle Mesh interface */
|
||||
/** Triangle Mesh interface (C-API)*/
|
||||
PL_DECLARE_HANDLE(plMeshInterfaceHandle);
|
||||
|
||||
/* Broadphase Scene/Proxy Handles */
|
||||
/** Broadphase Scene/Proxy Handles (C-API)*/
|
||||
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 */
|
||||
/** 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);
|
||||
|
||||
|
@ -19,10 +19,9 @@
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
#include "btAxisSweep3.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache)
|
||||
:btAxisSweep3Internal<unsigned short int>(worldAabbMin,worldAabbMax,0xfffe,0xffff,maxHandles,pairCache)
|
||||
btAxisSweep3::btAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache, bool disableRaycastAccelerator)
|
||||
:btAxisSweep3Internal<unsigned short int>(worldAabbMin,worldAabbMax,0xfffe,0xffff,maxHandles,pairCache,disableRaycastAccelerator)
|
||||
{
|
||||
// 1 handle is reserved as sentinel
|
||||
btAssert(maxHandles > 1 && maxHandles < 32767);
|
||||
@ -30,8 +29,8 @@ btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAab
|
||||
}
|
||||
|
||||
|
||||
bt32BitAxisSweep3::bt32BitAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles , btOverlappingPairCache* pairCache )
|
||||
:btAxisSweep3Internal<unsigned int>(worldAabbMin,worldAabbMax,0xfffffffe,0x7fffffff,maxHandles,pairCache)
|
||||
bt32BitAxisSweep3::bt32BitAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned int maxHandles , btOverlappingPairCache* pairCache , bool disableRaycastAccelerator)
|
||||
:btAxisSweep3Internal<unsigned int>(worldAabbMin,worldAabbMax,0xfffffffe,0x7fffffff,maxHandles,pairCache,disableRaycastAccelerator)
|
||||
{
|
||||
// 1 handle is reserved as sentinel
|
||||
btAssert(maxHandles > 1 && maxHandles < 2147483647);
|
||||
|
@ -19,12 +19,12 @@
|
||||
#ifndef AXIS_SWEEP_3_H
|
||||
#define AXIS_SWEEP_3_H
|
||||
|
||||
#include "LinearMath/btPoint3.h"
|
||||
#include "LinearMath/btVector3.h"
|
||||
#include "btOverlappingPairCache.h"
|
||||
#include "btBroadphaseInterface.h"
|
||||
#include "btBroadphaseProxy.h"
|
||||
#include "btOverlappingPairCallback.h"
|
||||
#include "btDbvtBroadphase.h"
|
||||
|
||||
//#define DEBUG_BROADPHASE 1
|
||||
#define USE_OVERLAP_TEST_ON_REMOVES 1
|
||||
@ -42,6 +42,7 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
class Edge
|
||||
{
|
||||
@ -61,8 +62,7 @@ public:
|
||||
// indexes into the edge arrays
|
||||
BP_FP_INT_TYPE m_minEdges[3], m_maxEdges[3]; // 6 * 2 = 12
|
||||
// BP_FP_INT_TYPE m_uniqueId;
|
||||
BP_FP_INT_TYPE m_pad;
|
||||
|
||||
btBroadphaseProxy* m_dbvtProxy;//for faster raycast
|
||||
//void* m_pOwner; this is now in btBroadphaseProxy.m_clientObject
|
||||
|
||||
SIMD_FORCE_INLINE void SetNextFree(BP_FP_INT_TYPE next) {m_minEdges[0] = next;}
|
||||
@ -71,8 +71,8 @@ public:
|
||||
|
||||
|
||||
protected:
|
||||
btPoint3 m_worldAabbMin; // overall system bounds
|
||||
btPoint3 m_worldAabbMax; // overall system bounds
|
||||
btVector3 m_worldAabbMin; // overall system bounds
|
||||
btVector3 m_worldAabbMax; // overall system bounds
|
||||
|
||||
btVector3 m_quantize; // scaling factor for quantization
|
||||
|
||||
@ -94,6 +94,12 @@ protected:
|
||||
|
||||
int m_invalidPair;
|
||||
|
||||
///additional dynamic aabb structure, used to accelerate ray cast queries.
|
||||
///can be disabled using a optional argument in the constructor
|
||||
btDbvtBroadphase* m_raycastAccelerator;
|
||||
btOverlappingPairCache* m_nullPairCache;
|
||||
|
||||
|
||||
// allocation/deallocation
|
||||
BP_FP_INT_TYPE allocHandle();
|
||||
void freeHandle(BP_FP_INT_TYPE handle);
|
||||
@ -108,7 +114,7 @@ protected:
|
||||
//Overlap* AddOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB);
|
||||
//void RemoveOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB);
|
||||
|
||||
void quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const;
|
||||
|
||||
|
||||
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 );
|
||||
@ -117,7 +123,7 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
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);
|
||||
btAxisSweep3Internal(const btVector3& worldAabbMin,const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache=0,bool disableRaycastAccelerator = false);
|
||||
|
||||
virtual ~btAxisSweep3Internal();
|
||||
|
||||
@ -128,17 +134,26 @@ public:
|
||||
|
||||
virtual void calculateOverlappingPairs(btDispatcher* dispatcher);
|
||||
|
||||
BP_FP_INT_TYPE addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
|
||||
BP_FP_INT_TYPE addHandle(const btVector3& aabbMin,const btVector3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
|
||||
void removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher);
|
||||
void updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax,btDispatcher* dispatcher);
|
||||
void updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
|
||||
SIMD_FORCE_INLINE Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;}
|
||||
|
||||
virtual void resetPool(btDispatcher* dispatcher);
|
||||
|
||||
void processAllOverlappingPairs(btOverlapCallback* callback);
|
||||
|
||||
//Broadphase Interface
|
||||
virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
|
||||
virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
|
||||
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
|
||||
virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
|
||||
|
||||
virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0));
|
||||
|
||||
void quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const;
|
||||
///unQuantize should be conservative: aabbMin/aabbMax should be larger then 'getAabb' result
|
||||
void unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
|
||||
|
||||
bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
|
||||
|
||||
@ -206,7 +221,7 @@ void btAxisSweep3<BP_FP_INT_TYPE>::debugPrintAxis(int axis, bool checkCardinalit
|
||||
}
|
||||
|
||||
if (checkCardinality)
|
||||
assert(numEdges == m_numHandles*2+1);
|
||||
btAssert(numEdges == m_numHandles*2+1);
|
||||
}
|
||||
#endif //DEBUG_BROADPHASE
|
||||
|
||||
@ -217,7 +232,12 @@ btBroadphaseProxy* btAxisSweep3Internal<BP_FP_INT_TYPE>::createProxy( const btV
|
||||
BP_FP_INT_TYPE handleId = addHandle(aabbMin,aabbMax, userPtr,collisionFilterGroup,collisionFilterMask,dispatcher,multiSapProxy);
|
||||
|
||||
Handle* handle = getHandle(handleId);
|
||||
|
||||
|
||||
if (m_raycastAccelerator)
|
||||
{
|
||||
btBroadphaseProxy* rayProxy = m_raycastAccelerator->createProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,dispatcher,0);
|
||||
handle->m_dbvtProxy = rayProxy;
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
@ -227,6 +247,8 @@ template <typename BP_FP_INT_TYPE>
|
||||
void btAxisSweep3Internal<BP_FP_INT_TYPE>::destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)
|
||||
{
|
||||
Handle* handle = static_cast<Handle*>(proxy);
|
||||
if (m_raycastAccelerator)
|
||||
m_raycastAccelerator->destroyProxy(handle->m_dbvtProxy,dispatcher);
|
||||
removeHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), dispatcher);
|
||||
}
|
||||
|
||||
@ -234,22 +256,80 @@ 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);
|
||||
handle->m_aabbMin = aabbMin;
|
||||
handle->m_aabbMax = aabbMax;
|
||||
updateHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), aabbMin, aabbMax,dispatcher);
|
||||
if (m_raycastAccelerator)
|
||||
m_raycastAccelerator->setAabb(handle->m_dbvtProxy,aabbMin,aabbMax,dispatcher);
|
||||
|
||||
}
|
||||
|
||||
template <typename BP_FP_INT_TYPE>
|
||||
void btAxisSweep3Internal<BP_FP_INT_TYPE>::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin,const btVector3& aabbMax)
|
||||
{
|
||||
if (m_raycastAccelerator)
|
||||
{
|
||||
m_raycastAccelerator->rayTest(rayFrom,rayTo,rayCallback,aabbMin,aabbMax);
|
||||
} else
|
||||
{
|
||||
//choose axis?
|
||||
BP_FP_INT_TYPE axis = 0;
|
||||
//for each proxy
|
||||
for (BP_FP_INT_TYPE i=1;i<m_numHandles*2+1;i++)
|
||||
{
|
||||
if (m_pEdges[axis][i].IsMax())
|
||||
{
|
||||
rayCallback.process(getHandle(m_pEdges[axis][i].m_handle));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename BP_FP_INT_TYPE>
|
||||
void btAxisSweep3Internal<BP_FP_INT_TYPE>::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const
|
||||
{
|
||||
Handle* pHandle = static_cast<Handle*>(proxy);
|
||||
aabbMin = pHandle->m_aabbMin;
|
||||
aabbMax = pHandle->m_aabbMax;
|
||||
}
|
||||
|
||||
|
||||
template <typename BP_FP_INT_TYPE>
|
||||
void btAxisSweep3Internal<BP_FP_INT_TYPE>::unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const
|
||||
{
|
||||
Handle* pHandle = static_cast<Handle*>(proxy);
|
||||
|
||||
unsigned short vecInMin[3];
|
||||
unsigned short vecInMax[3];
|
||||
|
||||
vecInMin[0] = m_pEdges[0][pHandle->m_minEdges[0]].m_pos ;
|
||||
vecInMax[0] = m_pEdges[0][pHandle->m_maxEdges[0]].m_pos +1 ;
|
||||
vecInMin[1] = m_pEdges[1][pHandle->m_minEdges[1]].m_pos ;
|
||||
vecInMax[1] = m_pEdges[1][pHandle->m_maxEdges[1]].m_pos +1 ;
|
||||
vecInMin[2] = m_pEdges[2][pHandle->m_minEdges[2]].m_pos ;
|
||||
vecInMax[2] = m_pEdges[2][pHandle->m_maxEdges[2]].m_pos +1 ;
|
||||
|
||||
aabbMin.setValue((btScalar)(vecInMin[0]) / (m_quantize.getX()),(btScalar)(vecInMin[1]) / (m_quantize.getY()),(btScalar)(vecInMin[2]) / (m_quantize.getZ()));
|
||||
aabbMin += m_worldAabbMin;
|
||||
|
||||
aabbMax.setValue((btScalar)(vecInMax[0]) / (m_quantize.getX()),(btScalar)(vecInMax[1]) / (m_quantize.getY()),(btScalar)(vecInMax[2]) / (m_quantize.getZ()));
|
||||
aabbMax += m_worldAabbMin;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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 userMaxHandles, btOverlappingPairCache* pairCache )
|
||||
btAxisSweep3Internal<BP_FP_INT_TYPE>::btAxisSweep3Internal(const btVector3& worldAabbMin,const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel,BP_FP_INT_TYPE userMaxHandles, btOverlappingPairCache* pairCache , bool disableRaycastAccelerator)
|
||||
:m_bpHandleMask(handleMask),
|
||||
m_handleSentinel(handleSentinel),
|
||||
m_pairCache(pairCache),
|
||||
m_userPairCallback(0),
|
||||
m_ownsPairCache(false),
|
||||
m_invalidPair(0)
|
||||
m_invalidPair(0),
|
||||
m_raycastAccelerator(0)
|
||||
{
|
||||
BP_FP_INT_TYPE maxHandles = static_cast<BP_FP_INT_TYPE>(userMaxHandles+1);//need to add one sentinel handle
|
||||
|
||||
@ -260,7 +340,14 @@ m_invalidPair(0)
|
||||
m_ownsPairCache = true;
|
||||
}
|
||||
|
||||
//assert(bounds.HasVolume());
|
||||
if (!disableRaycastAccelerator)
|
||||
{
|
||||
m_nullPairCache = new (btAlignedAlloc(sizeof(btNullPairCache),16)) btNullPairCache();
|
||||
m_raycastAccelerator = new (btAlignedAlloc(sizeof(btDbvtBroadphase),16)) btDbvtBroadphase(m_nullPairCache);//m_pairCache);
|
||||
m_raycastAccelerator->m_deferedcollide = true;//don't add/remove pairs
|
||||
}
|
||||
|
||||
//btAssert(bounds.HasVolume());
|
||||
|
||||
// init bounds
|
||||
m_worldAabbMin = worldAabbMin;
|
||||
@ -320,7 +407,14 @@ m_invalidPair(0)
|
||||
template <typename BP_FP_INT_TYPE>
|
||||
btAxisSweep3Internal<BP_FP_INT_TYPE>::~btAxisSweep3Internal()
|
||||
{
|
||||
|
||||
if (m_raycastAccelerator)
|
||||
{
|
||||
m_nullPairCache->~btOverlappingPairCache();
|
||||
btAlignedFree(m_nullPairCache);
|
||||
m_raycastAccelerator->~btDbvtBroadphase();
|
||||
btAlignedFree (m_raycastAccelerator);
|
||||
}
|
||||
|
||||
for (int i = 2; i >= 0; i--)
|
||||
{
|
||||
btAlignedFree(m_pEdgesRawPtr[i]);
|
||||
@ -335,27 +429,31 @@ btAxisSweep3Internal<BP_FP_INT_TYPE>::~btAxisSweep3Internal()
|
||||
}
|
||||
|
||||
template <typename BP_FP_INT_TYPE>
|
||||
void btAxisSweep3Internal<BP_FP_INT_TYPE>::quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const
|
||||
void btAxisSweep3Internal<BP_FP_INT_TYPE>::quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const
|
||||
{
|
||||
btPoint3 clampedPoint(point);
|
||||
|
||||
|
||||
|
||||
#ifdef OLD_CLAMPING_METHOD
|
||||
///problem with this clamping method is that the floating point during quantization might still go outside the range [(0|isMax) .. (m_handleSentinel&m_bpHandleMask]|isMax]
|
||||
///see http://code.google.com/p/bullet/issues/detail?id=87
|
||||
btVector3 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);
|
||||
|
||||
#else
|
||||
btVector3 v = (point - m_worldAabbMin) * m_quantize;
|
||||
out[0]=(v[0]<=0)?(BP_FP_INT_TYPE)isMax:(v[0]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[0]&m_bpHandleMask)|isMax);
|
||||
out[1]=(v[1]<=0)?(BP_FP_INT_TYPE)isMax:(v[1]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[1]&m_bpHandleMask)|isMax);
|
||||
out[2]=(v[2]<=0)?(BP_FP_INT_TYPE)isMax:(v[2]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[2]&m_bpHandleMask)|isMax);
|
||||
#endif //OLD_CLAMPING_METHOD
|
||||
}
|
||||
|
||||
|
||||
template <typename BP_FP_INT_TYPE>
|
||||
BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::allocHandle()
|
||||
{
|
||||
assert(m_firstFreeHandle);
|
||||
btAssert(m_firstFreeHandle);
|
||||
|
||||
BP_FP_INT_TYPE handle = m_firstFreeHandle;
|
||||
m_firstFreeHandle = getHandle(handle)->GetNextFree();
|
||||
@ -367,7 +465,7 @@ BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::allocHandle()
|
||||
template <typename BP_FP_INT_TYPE>
|
||||
void btAxisSweep3Internal<BP_FP_INT_TYPE>::freeHandle(BP_FP_INT_TYPE handle)
|
||||
{
|
||||
assert(handle > 0 && handle < m_maxHandles);
|
||||
btAssert(handle > 0 && handle < m_maxHandles);
|
||||
|
||||
getHandle(handle)->SetNextFree(m_firstFreeHandle);
|
||||
m_firstFreeHandle = handle;
|
||||
@ -377,7 +475,7 @@ void btAxisSweep3Internal<BP_FP_INT_TYPE>::freeHandle(BP_FP_INT_TYPE handle)
|
||||
|
||||
|
||||
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,void* multiSapProxy)
|
||||
BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::addHandle(const btVector3& aabbMin,const btVector3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy)
|
||||
{
|
||||
// quantize the bounds
|
||||
BP_FP_INT_TYPE min[3], max[3];
|
||||
@ -440,7 +538,7 @@ void btAxisSweep3Internal<BP_FP_INT_TYPE>::removeHandle(BP_FP_INT_TYPE handle,bt
|
||||
|
||||
//explicitly remove the pairs containing the proxy
|
||||
//we could do it also in the sortMinUp (passing true)
|
||||
//todo: compare performance
|
||||
///@todo: compare performance
|
||||
if (!m_pairCache->hasDeferredRemoval())
|
||||
{
|
||||
m_pairCache->removeOverlappingPairsContainingProxy(pHandle,dispatcher);
|
||||
@ -489,6 +587,21 @@ void btAxisSweep3Internal<BP_FP_INT_TYPE>::removeHandle(BP_FP_INT_TYPE handle,bt
|
||||
|
||||
}
|
||||
|
||||
template <typename BP_FP_INT_TYPE>
|
||||
void btAxisSweep3Internal<BP_FP_INT_TYPE>::resetPool(btDispatcher* dispatcher)
|
||||
{
|
||||
if (m_numHandles == 0)
|
||||
{
|
||||
m_firstFreeHandle = 1;
|
||||
{
|
||||
for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < m_maxHandles; i++)
|
||||
m_pHandles[i].SetNextFree(static_cast<BP_FP_INT_TYPE>(i + 1));
|
||||
m_pHandles[m_maxHandles - 1].SetNextFree(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern int gOverlappingPairs;
|
||||
//#include <stdio.h>
|
||||
|
||||
@ -529,6 +642,7 @@ void btAxisSweep3Internal<BP_FP_INT_TYPE>::calculateOverlappingPairs(btDispatche
|
||||
|
||||
if (!isDuplicate)
|
||||
{
|
||||
///important to use an AABB test that is consistent with the broadphase
|
||||
bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1);
|
||||
|
||||
if (hasOverlap)
|
||||
@ -574,10 +688,6 @@ void btAxisSweep3Internal<BP_FP_INT_TYPE>::calculateOverlappingPairs(btDispatche
|
||||
//printf("overlappingPairArray.size()=%d\n",overlappingPairArray.size());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -616,10 +726,10 @@ bool btAxisSweep3Internal<BP_FP_INT_TYPE>::testOverlap2D(const Handle* pHandleA,
|
||||
}
|
||||
|
||||
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)
|
||||
void btAxisSweep3Internal<BP_FP_INT_TYPE>::updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher)
|
||||
{
|
||||
// assert(bounds.IsFinite());
|
||||
//assert(bounds.HasVolume());
|
||||
// btAssert(bounds.IsFinite());
|
||||
//btAssert(bounds.HasVolume());
|
||||
|
||||
Handle* pHandle = getHandle(handle);
|
||||
|
||||
@ -895,7 +1005,7 @@ class btAxisSweep3 : public btAxisSweep3Internal<unsigned short int>
|
||||
{
|
||||
public:
|
||||
|
||||
btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0);
|
||||
btAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false);
|
||||
|
||||
};
|
||||
|
||||
@ -906,7 +1016,7 @@ class bt32BitAxisSweep3 : public btAxisSweep3Internal<unsigned int>
|
||||
{
|
||||
public:
|
||||
|
||||
bt32BitAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0);
|
||||
bt32BitAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false);
|
||||
|
||||
};
|
||||
|
||||
|
@ -21,8 +21,22 @@ subject to the following restrictions:
|
||||
struct btDispatcherInfo;
|
||||
class btDispatcher;
|
||||
#include "btBroadphaseProxy.h"
|
||||
|
||||
class btOverlappingPairCache;
|
||||
|
||||
|
||||
|
||||
struct btBroadphaseRayCallback
|
||||
{
|
||||
///added some cached data to accelerate ray-AABB tests
|
||||
btVector3 m_rayDirectionInverse;
|
||||
unsigned int m_signs[3];
|
||||
btScalar m_lambda_max;
|
||||
|
||||
virtual ~btBroadphaseRayCallback() {}
|
||||
virtual bool process(const btBroadphaseProxy* proxy) = 0;
|
||||
};
|
||||
|
||||
#include "LinearMath/btVector3.h"
|
||||
|
||||
///The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs.
|
||||
@ -36,7 +50,10 @@ public:
|
||||
virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy) =0;
|
||||
virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)=0;
|
||||
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)=0;
|
||||
|
||||
virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const =0;
|
||||
|
||||
virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0)) = 0;
|
||||
|
||||
///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb
|
||||
virtual void calculateOverlappingPairs(btDispatcher* dispatcher)=0;
|
||||
|
||||
@ -47,6 +64,9 @@ public:
|
||||
///will add some transform later
|
||||
virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const =0;
|
||||
|
||||
///reset broadphase internal structures, to ensure determinism/reproducability
|
||||
virtual void resetPool(btDispatcher* dispatcher) {};
|
||||
|
||||
virtual void printStats() = 0;
|
||||
|
||||
};
|
||||
|
@ -17,20 +17,24 @@ subject to the following restrictions:
|
||||
#define BROADPHASE_PROXY_H
|
||||
|
||||
#include "LinearMath/btScalar.h" //for SIMD_FORCE_INLINE
|
||||
#include "LinearMath/btVector3.h"
|
||||
#include "LinearMath/btAlignedAllocator.h"
|
||||
|
||||
|
||||
/// btDispatcher uses these types
|
||||
/// IMPORTANT NOTE:The types are ordered polyhedral, implicit convex and concave
|
||||
/// to facilitate type checking
|
||||
/// CUSTOM_POLYHEDRAL_SHAPE_TYPE,CUSTOM_CONVEX_SHAPE_TYPE and CUSTOM_CONCAVE_SHAPE_TYPE can be used to extend Bullet without modifying source code
|
||||
enum BroadphaseNativeTypes
|
||||
{
|
||||
// polyhedral convex shapes
|
||||
// polyhedral convex shapes
|
||||
BOX_SHAPE_PROXYTYPE,
|
||||
TRIANGLE_SHAPE_PROXYTYPE,
|
||||
TETRAHEDRAL_SHAPE_PROXYTYPE,
|
||||
CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE,
|
||||
CONVEX_HULL_SHAPE_PROXYTYPE,
|
||||
CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE,
|
||||
CUSTOM_POLYHEDRAL_SHAPE_TYPE,
|
||||
//implicit convex shapes
|
||||
IMPLICIT_CONVEX_SHAPES_START_HERE,
|
||||
SPHERE_SHAPE_PROXYTYPE,
|
||||
@ -42,6 +46,7 @@ IMPLICIT_CONVEX_SHAPES_START_HERE,
|
||||
UNIFORM_SCALING_SHAPE_PROXYTYPE,
|
||||
MINKOWSKI_SUM_SHAPE_PROXYTYPE,
|
||||
MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE,
|
||||
CUSTOM_CONVEX_SHAPE_TYPE,
|
||||
//concave shapes
|
||||
CONCAVE_SHAPES_START_HERE,
|
||||
//keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy!
|
||||
@ -58,13 +63,18 @@ CONCAVE_SHAPES_START_HERE,
|
||||
|
||||
EMPTY_SHAPE_PROXYTYPE,
|
||||
STATIC_PLANE_PROXYTYPE,
|
||||
CUSTOM_CONCAVE_SHAPE_TYPE,
|
||||
CONCAVE_SHAPES_END_HERE,
|
||||
|
||||
COMPOUND_SHAPE_PROXYTYPE,
|
||||
|
||||
SOFTBODY_SHAPE_PROXYTYPE,
|
||||
HFFLUID_SHAPE_PROXYTYPE,
|
||||
HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE,
|
||||
INVALID_SHAPE_PROXYTYPE,
|
||||
|
||||
MAX_BROADPHASE_COLLISION_TYPES
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -83,20 +93,20 @@ BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
KinematicFilter = 4,
|
||||
DebrisFilter = 8,
|
||||
SensorTrigger = 16,
|
||||
CharacterFilter = 32,
|
||||
AllFilter = -1 //all bits sets: DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger
|
||||
};
|
||||
|
||||
//Usually the client btCollisionObject or Rigidbody class
|
||||
void* m_clientObject;
|
||||
|
||||
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.
|
||||
|
||||
btVector3 m_aabbMin;
|
||||
btVector3 m_aabbMax;
|
||||
|
||||
SIMD_FORCE_INLINE int getUid() const
|
||||
{
|
||||
return m_uniqueId;
|
||||
@ -107,10 +117,12 @@ BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
{
|
||||
}
|
||||
|
||||
btBroadphaseProxy(void* userPtr,short int collisionFilterGroup, short int collisionFilterMask,void* multiSapParentProxy=0)
|
||||
btBroadphaseProxy(const btVector3& aabbMin,const btVector3& aabbMax,void* userPtr,short int collisionFilterGroup, short int collisionFilterMask,void* multiSapParentProxy=0)
|
||||
:m_clientObject(userPtr),
|
||||
m_collisionFilterGroup(collisionFilterGroup),
|
||||
m_collisionFilterMask(collisionFilterMask)
|
||||
m_collisionFilterMask(collisionFilterMask),
|
||||
m_aabbMin(aabbMin),
|
||||
m_aabbMax(aabbMax)
|
||||
{
|
||||
m_multiSapParentProxy = multiSapParentProxy;
|
||||
}
|
||||
@ -159,7 +171,7 @@ ATTRIBUTE_ALIGNED16(struct) btBroadphasePair
|
||||
m_pProxy0(0),
|
||||
m_pProxy1(0),
|
||||
m_algorithm(0),
|
||||
m_userInfo(0)
|
||||
m_internalInfo1(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -169,14 +181,14 @@ BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
: m_pProxy0(other.m_pProxy0),
|
||||
m_pProxy1(other.m_pProxy1),
|
||||
m_algorithm(other.m_algorithm),
|
||||
m_userInfo(other.m_userInfo)
|
||||
m_internalInfo1(other.m_internalInfo1)
|
||||
{
|
||||
}
|
||||
btBroadphasePair(btBroadphaseProxy& proxy0,btBroadphaseProxy& proxy1)
|
||||
{
|
||||
|
||||
//keep them sorted, so the std::set operations work
|
||||
if (&proxy0 < &proxy1)
|
||||
if (proxy0.m_uniqueId < proxy1.m_uniqueId)
|
||||
{
|
||||
m_pProxy0 = &proxy0;
|
||||
m_pProxy1 = &proxy1;
|
||||
@ -188,7 +200,7 @@ BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
}
|
||||
|
||||
m_algorithm = 0;
|
||||
m_userInfo = 0;
|
||||
m_internalInfo1 = 0;
|
||||
|
||||
}
|
||||
|
||||
@ -196,7 +208,7 @@ BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
btBroadphaseProxy* m_pProxy1;
|
||||
|
||||
mutable btCollisionAlgorithm* m_algorithm;
|
||||
mutable void* m_userInfo;
|
||||
union { void* m_internalInfo1; int m_internalTmpValue;};//don't use this data, it will be removed in future version.
|
||||
|
||||
};
|
||||
|
||||
@ -217,8 +229,13 @@ class btBroadphasePairSortPredicate
|
||||
|
||||
bool operator() ( const btBroadphasePair& a, const btBroadphasePair& b )
|
||||
{
|
||||
return a.m_pProxy0 > b.m_pProxy0 ||
|
||||
(a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 > b.m_pProxy1) ||
|
||||
const int uidA0 = a.m_pProxy0 ? a.m_pProxy0->m_uniqueId : -1;
|
||||
const int uidB0 = b.m_pProxy0 ? b.m_pProxy0->m_uniqueId : -1;
|
||||
const int uidA1 = a.m_pProxy1 ? a.m_pProxy1->m_uniqueId : -1;
|
||||
const int uidB1 = b.m_pProxy1 ? b.m_pProxy1->m_uniqueId : -1;
|
||||
|
||||
return uidA0 > uidB0 ||
|
||||
(a.m_pProxy0 == b.m_pProxy0 && uidA1 > uidB1) ||
|
||||
(a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 == b.m_pProxy1 && a.m_algorithm > b.m_algorithm);
|
||||
}
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -26,19 +26,19 @@ subject to the following restrictions:
|
||||
|
||||
#if DBVT_BP_PROFILE
|
||||
struct ProfileScope
|
||||
{
|
||||
{
|
||||
__forceinline ProfileScope(btClock& clock,unsigned long& value) :
|
||||
m_clock(&clock),m_value(&value),m_base(clock.getTimeMicroseconds())
|
||||
{
|
||||
}
|
||||
m_clock(&clock),m_value(&value),m_base(clock.getTimeMicroseconds())
|
||||
{
|
||||
}
|
||||
__forceinline ~ProfileScope()
|
||||
{
|
||||
{
|
||||
(*m_value)+=m_clock->getTimeMicroseconds()-m_base;
|
||||
}
|
||||
}
|
||||
btClock* m_clock;
|
||||
unsigned long* m_value;
|
||||
unsigned long m_base;
|
||||
};
|
||||
};
|
||||
#define SPC(_value_) ProfileScope spc_scope(m_clock,_value_)
|
||||
#else
|
||||
#define SPC(_value_)
|
||||
@ -52,35 +52,35 @@ struct ProfileScope
|
||||
template <typename T>
|
||||
static inline void listappend(T* item,T*& list)
|
||||
{
|
||||
item->links[0]=0;
|
||||
item->links[1]=list;
|
||||
if(list) list->links[0]=item;
|
||||
list=item;
|
||||
item->links[0]=0;
|
||||
item->links[1]=list;
|
||||
if(list) list->links[0]=item;
|
||||
list=item;
|
||||
}
|
||||
|
||||
//
|
||||
template <typename T>
|
||||
static inline void listremove(T* item,T*& list)
|
||||
{
|
||||
if(item->links[0]) item->links[0]->links[1]=item->links[1]; else list=item->links[1];
|
||||
if(item->links[1]) item->links[1]->links[0]=item->links[0];
|
||||
if(item->links[0]) item->links[0]->links[1]=item->links[1]; else list=item->links[1];
|
||||
if(item->links[1]) item->links[1]->links[0]=item->links[0];
|
||||
}
|
||||
|
||||
//
|
||||
template <typename T>
|
||||
static inline int listcount(T* root)
|
||||
{
|
||||
int n=0;
|
||||
while(root) { ++n;root=root->links[1]; }
|
||||
return(n);
|
||||
int n=0;
|
||||
while(root) { ++n;root=root->links[1]; }
|
||||
return(n);
|
||||
}
|
||||
|
||||
//
|
||||
template <typename T>
|
||||
static inline void clear(T& value)
|
||||
{
|
||||
static const struct ZeroDummy : T {} zerodummy;
|
||||
value=zerodummy;
|
||||
static const struct ZeroDummy : T {} zerodummy;
|
||||
value=zerodummy;
|
||||
}
|
||||
|
||||
//
|
||||
@ -90,25 +90,26 @@ value=zerodummy;
|
||||
/* Tree collider */
|
||||
struct btDbvtTreeCollider : btDbvt::ICollide
|
||||
{
|
||||
btDbvtBroadphase* pbp;
|
||||
btDbvtProxy* proxy;
|
||||
btDbvtTreeCollider(btDbvtBroadphase* p) : pbp(p) {}
|
||||
void Process(const btDbvtNode* na,const btDbvtNode* nb)
|
||||
btDbvtBroadphase* pbp;
|
||||
btDbvtProxy* proxy;
|
||||
btDbvtTreeCollider(btDbvtBroadphase* p) : pbp(p) {}
|
||||
void Process(const btDbvtNode* na,const btDbvtNode* nb)
|
||||
{
|
||||
if(na!=nb)
|
||||
if(na!=nb)
|
||||
{
|
||||
btDbvtProxy* pa=(btDbvtProxy*)na->data;
|
||||
btDbvtProxy* pb=(btDbvtProxy*)nb->data;
|
||||
#if DBVT_BP_SORTPAIRS
|
||||
if(pa>pb) btSwap(pa,pb);
|
||||
#endif
|
||||
pbp->m_paircache->addOverlappingPair(pa,pb);
|
||||
++pbp->m_newpairs;
|
||||
btDbvtProxy* pa=(btDbvtProxy*)na->data;
|
||||
btDbvtProxy* pb=(btDbvtProxy*)nb->data;
|
||||
#if DBVT_BP_SORTPAIRS
|
||||
if(pa->m_uniqueId>pb->m_uniqueId)
|
||||
btSwap(pa,pb);
|
||||
#endif
|
||||
pbp->m_paircache->addOverlappingPair(pa,pb);
|
||||
++pbp->m_newpairs;
|
||||
}
|
||||
}
|
||||
void Process(const btDbvtNode* n)
|
||||
void Process(const btDbvtNode* n)
|
||||
{
|
||||
Process(n,proxy->leaf);
|
||||
Process(n,proxy->leaf);
|
||||
}
|
||||
};
|
||||
|
||||
@ -119,147 +120,197 @@ void Process(const btDbvtNode* n)
|
||||
//
|
||||
btDbvtBroadphase::btDbvtBroadphase(btOverlappingPairCache* paircache)
|
||||
{
|
||||
m_deferedcollide = false;
|
||||
m_needcleanup = true;
|
||||
m_releasepaircache = (paircache!=0)?false:true;
|
||||
m_prediction = 1/(btScalar)2;
|
||||
m_stageCurrent = 0;
|
||||
m_fixedleft = 0;
|
||||
m_fupdates = 1;
|
||||
m_dupdates = 0;
|
||||
m_cupdates = 10;
|
||||
m_newpairs = 1;
|
||||
m_updates_call = 0;
|
||||
m_updates_done = 0;
|
||||
m_updates_ratio = 0;
|
||||
m_paircache = paircache?
|
||||
paircache :
|
||||
new(btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache();
|
||||
m_gid = 0;
|
||||
m_pid = 0;
|
||||
m_cid = 0;
|
||||
for(int i=0;i<=STAGECOUNT;++i)
|
||||
m_deferedcollide = false;
|
||||
m_needcleanup = true;
|
||||
m_releasepaircache = (paircache!=0)?false:true;
|
||||
m_prediction = 1/(btScalar)2;
|
||||
m_stageCurrent = 0;
|
||||
m_fixedleft = 0;
|
||||
m_fupdates = 1;
|
||||
m_dupdates = 0;
|
||||
m_cupdates = 10;
|
||||
m_newpairs = 1;
|
||||
m_updates_call = 0;
|
||||
m_updates_done = 0;
|
||||
m_updates_ratio = 0;
|
||||
m_paircache = paircache? paircache : new(btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache();
|
||||
m_gid = 0;
|
||||
m_pid = 0;
|
||||
m_cid = 0;
|
||||
for(int i=0;i<=STAGECOUNT;++i)
|
||||
{
|
||||
m_stageRoots[i]=0;
|
||||
m_stageRoots[i]=0;
|
||||
}
|
||||
#if DBVT_BP_PROFILE
|
||||
clear(m_profiling);
|
||||
clear(m_profiling);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
btDbvtBroadphase::~btDbvtBroadphase()
|
||||
{
|
||||
if(m_releasepaircache)
|
||||
{
|
||||
m_paircache->~btOverlappingPairCache();
|
||||
btAlignedFree(m_paircache);
|
||||
}
|
||||
if(m_releasepaircache)
|
||||
{
|
||||
m_paircache->~btOverlappingPairCache();
|
||||
btAlignedFree(m_paircache);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
btBroadphaseProxy* btDbvtBroadphase::createProxy( const btVector3& aabbMin,
|
||||
const btVector3& aabbMax,
|
||||
int /*shapeType*/,
|
||||
void* userPtr,
|
||||
short int collisionFilterGroup,
|
||||
short int collisionFilterMask,
|
||||
btDispatcher* /*dispatcher*/,
|
||||
void* /*multiSapProxy*/)
|
||||
const btVector3& aabbMax,
|
||||
int /*shapeType*/,
|
||||
void* userPtr,
|
||||
short int collisionFilterGroup,
|
||||
short int collisionFilterMask,
|
||||
btDispatcher* /*dispatcher*/,
|
||||
void* /*multiSapProxy*/)
|
||||
{
|
||||
btDbvtProxy* proxy=new(btAlignedAlloc(sizeof(btDbvtProxy),16)) btDbvtProxy( userPtr,
|
||||
collisionFilterGroup,
|
||||
collisionFilterMask);
|
||||
proxy->aabb = btDbvtVolume::FromMM(aabbMin,aabbMax);
|
||||
proxy->stage = m_stageCurrent;
|
||||
proxy->m_uniqueId = ++m_gid;
|
||||
proxy->leaf = m_sets[0].insert(proxy->aabb,proxy);
|
||||
listappend(proxy,m_stageRoots[m_stageCurrent]);
|
||||
if(!m_deferedcollide)
|
||||
btDbvtProxy* proxy=new(btAlignedAlloc(sizeof(btDbvtProxy),16)) btDbvtProxy( aabbMin,aabbMax,userPtr,
|
||||
collisionFilterGroup,
|
||||
collisionFilterMask);
|
||||
|
||||
btDbvtAabbMm aabb = btDbvtVolume::FromMM(aabbMin,aabbMax);
|
||||
|
||||
//bproxy->aabb = btDbvtVolume::FromMM(aabbMin,aabbMax);
|
||||
proxy->stage = m_stageCurrent;
|
||||
proxy->m_uniqueId = ++m_gid;
|
||||
proxy->leaf = m_sets[0].insert(aabb,proxy);
|
||||
listappend(proxy,m_stageRoots[m_stageCurrent]);
|
||||
if(!m_deferedcollide)
|
||||
{
|
||||
btDbvtTreeCollider collider(this);
|
||||
collider.proxy=proxy;
|
||||
btDbvt::collideTV(m_sets[0].m_root,proxy->aabb,collider);
|
||||
btDbvt::collideTV(m_sets[1].m_root,proxy->aabb,collider);
|
||||
btDbvtTreeCollider collider(this);
|
||||
collider.proxy=proxy;
|
||||
m_sets[0].collideTV(m_sets[0].m_root,aabb,collider);
|
||||
m_sets[1].collideTV(m_sets[1].m_root,aabb,collider);
|
||||
}
|
||||
return(proxy);
|
||||
return(proxy);
|
||||
}
|
||||
|
||||
//
|
||||
void btDbvtBroadphase::destroyProxy( btBroadphaseProxy* absproxy,
|
||||
btDispatcher* dispatcher)
|
||||
btDispatcher* dispatcher)
|
||||
{
|
||||
btDbvtProxy* proxy=(btDbvtProxy*)absproxy;
|
||||
if(proxy->stage==STAGECOUNT)
|
||||
m_sets[1].remove(proxy->leaf);
|
||||
btDbvtProxy* proxy=(btDbvtProxy*)absproxy;
|
||||
if(proxy->stage==STAGECOUNT)
|
||||
m_sets[1].remove(proxy->leaf);
|
||||
else
|
||||
m_sets[0].remove(proxy->leaf);
|
||||
listremove(proxy,m_stageRoots[proxy->stage]);
|
||||
m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher);
|
||||
btAlignedFree(proxy);
|
||||
m_needcleanup=true;
|
||||
m_sets[0].remove(proxy->leaf);
|
||||
listremove(proxy,m_stageRoots[proxy->stage]);
|
||||
m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher);
|
||||
btAlignedFree(proxy);
|
||||
m_needcleanup=true;
|
||||
}
|
||||
|
||||
void btDbvtBroadphase::getAabb(btBroadphaseProxy* absproxy,btVector3& aabbMin, btVector3& aabbMax ) const
|
||||
{
|
||||
btDbvtProxy* proxy=(btDbvtProxy*)absproxy;
|
||||
aabbMin = proxy->m_aabbMin;
|
||||
aabbMax = proxy->m_aabbMax;
|
||||
}
|
||||
|
||||
struct BroadphaseRayTester : btDbvt::ICollide
|
||||
{
|
||||
btBroadphaseRayCallback& m_rayCallback;
|
||||
BroadphaseRayTester(btBroadphaseRayCallback& orgCallback)
|
||||
:m_rayCallback(orgCallback)
|
||||
{
|
||||
}
|
||||
void Process(const btDbvtNode* leaf)
|
||||
{
|
||||
btDbvtProxy* proxy=(btDbvtProxy*)leaf->data;
|
||||
m_rayCallback.process(proxy);
|
||||
}
|
||||
};
|
||||
|
||||
void btDbvtBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin,const btVector3& aabbMax)
|
||||
{
|
||||
BroadphaseRayTester callback(rayCallback);
|
||||
|
||||
m_sets[0].rayTestInternal( m_sets[0].m_root,
|
||||
rayFrom,
|
||||
rayTo,
|
||||
rayCallback.m_rayDirectionInverse,
|
||||
rayCallback.m_signs,
|
||||
rayCallback.m_lambda_max,
|
||||
aabbMin,
|
||||
aabbMax,
|
||||
callback);
|
||||
|
||||
m_sets[1].rayTestInternal( m_sets[1].m_root,
|
||||
rayFrom,
|
||||
rayTo,
|
||||
rayCallback.m_rayDirectionInverse,
|
||||
rayCallback.m_signs,
|
||||
rayCallback.m_lambda_max,
|
||||
aabbMin,
|
||||
aabbMax,
|
||||
callback);
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
void btDbvtBroadphase::setAabb( btBroadphaseProxy* absproxy,
|
||||
const btVector3& aabbMin,
|
||||
const btVector3& aabbMax,
|
||||
btDispatcher* /*dispatcher*/)
|
||||
const btVector3& aabbMin,
|
||||
const btVector3& aabbMax,
|
||||
btDispatcher* /*dispatcher*/)
|
||||
{
|
||||
btDbvtProxy* proxy=(btDbvtProxy*)absproxy;
|
||||
ATTRIBUTE_ALIGNED16(btDbvtVolume) aabb=btDbvtVolume::FromMM(aabbMin,aabbMax);
|
||||
btDbvtProxy* proxy=(btDbvtProxy*)absproxy;
|
||||
ATTRIBUTE_ALIGNED16(btDbvtVolume) aabb=btDbvtVolume::FromMM(aabbMin,aabbMax);
|
||||
#if DBVT_BP_PREVENTFALSEUPDATE
|
||||
if(NotEqual(aabb,proxy->leaf->volume))
|
||||
if(NotEqual(aabb,proxy->leaf->volume))
|
||||
#endif
|
||||
{
|
||||
bool docollide=false;
|
||||
if(proxy->stage==STAGECOUNT)
|
||||
bool docollide=false;
|
||||
if(proxy->stage==STAGECOUNT)
|
||||
{/* fixed -> dynamic set */
|
||||
m_sets[1].remove(proxy->leaf);
|
||||
proxy->leaf=m_sets[0].insert(aabb,proxy);
|
||||
docollide=true;
|
||||
m_sets[1].remove(proxy->leaf);
|
||||
proxy->leaf=m_sets[0].insert(aabb,proxy);
|
||||
docollide=true;
|
||||
}
|
||||
else
|
||||
{/* dynamic set */
|
||||
++m_updates_call;
|
||||
if(Intersect(proxy->leaf->volume,aabb))
|
||||
++m_updates_call;
|
||||
if(Intersect(proxy->leaf->volume,aabb))
|
||||
{/* Moving */
|
||||
const btVector3 delta=aabbMin-proxy->aabb.Mins();
|
||||
btVector3 velocity(aabb.Extents()*m_prediction);
|
||||
if(delta[0]<0) velocity[0]=-velocity[0];
|
||||
if(delta[1]<0) velocity[1]=-velocity[1];
|
||||
if(delta[2]<0) velocity[2]=-velocity[2];
|
||||
if (
|
||||
#ifdef DBVT_BP_MARGIN
|
||||
m_sets[0].update(proxy->leaf,aabb,velocity,DBVT_BP_MARGIN)
|
||||
#else
|
||||
m_sets[0].update(proxy->leaf,aabb,velocity)
|
||||
#endif
|
||||
)
|
||||
|
||||
const btVector3 delta=aabbMin-proxy->m_aabbMin;
|
||||
btVector3 velocity(((proxy->m_aabbMax-proxy->m_aabbMin)/2)*m_prediction);
|
||||
if(delta[0]<0) velocity[0]=-velocity[0];
|
||||
if(delta[1]<0) velocity[1]=-velocity[1];
|
||||
if(delta[2]<0) velocity[2]=-velocity[2];
|
||||
if (
|
||||
#ifdef DBVT_BP_MARGIN
|
||||
m_sets[0].update(proxy->leaf,aabb,velocity,DBVT_BP_MARGIN)
|
||||
#else
|
||||
m_sets[0].update(proxy->leaf,aabb,velocity)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
++m_updates_done;
|
||||
docollide=true;
|
||||
++m_updates_done;
|
||||
docollide=true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{/* Teleporting */
|
||||
m_sets[0].update(proxy->leaf,aabb);
|
||||
++m_updates_done;
|
||||
docollide=true;
|
||||
m_sets[0].update(proxy->leaf,aabb);
|
||||
++m_updates_done;
|
||||
docollide=true;
|
||||
}
|
||||
}
|
||||
listremove(proxy,m_stageRoots[proxy->stage]);
|
||||
proxy->aabb = aabb;
|
||||
proxy->stage = m_stageCurrent;
|
||||
listappend(proxy,m_stageRoots[m_stageCurrent]);
|
||||
if(docollide)
|
||||
listremove(proxy,m_stageRoots[proxy->stage]);
|
||||
proxy->m_aabbMin = aabbMin;
|
||||
proxy->m_aabbMax = aabbMax;
|
||||
proxy->stage = m_stageCurrent;
|
||||
listappend(proxy,m_stageRoots[m_stageCurrent]);
|
||||
if(docollide)
|
||||
{
|
||||
m_needcleanup=true;
|
||||
if(!m_deferedcollide)
|
||||
m_needcleanup=true;
|
||||
if(!m_deferedcollide)
|
||||
{
|
||||
btDbvtTreeCollider collider(this);
|
||||
btDbvt::collideTT(m_sets[1].m_root,proxy->leaf,collider);
|
||||
btDbvt::collideTT(m_sets[0].m_root,proxy->leaf,collider);
|
||||
btDbvtTreeCollider collider(this);
|
||||
m_sets[1].collideTTpersistentStack(m_sets[1].m_root,proxy->leaf,collider);
|
||||
m_sets[0].collideTTpersistentStack(m_sets[0].m_root,proxy->leaf,collider);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -268,132 +319,226 @@ if(NotEqual(aabb,proxy->leaf->volume))
|
||||
//
|
||||
void btDbvtBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
|
||||
{
|
||||
collide(dispatcher);
|
||||
collide(dispatcher);
|
||||
#if DBVT_BP_PROFILE
|
||||
if(0==(m_pid%DBVT_BP_PROFILING_RATE))
|
||||
if(0==(m_pid%DBVT_BP_PROFILING_RATE))
|
||||
{
|
||||
printf("fixed(%u) dynamics(%u) pairs(%u)\r\n",m_sets[1].m_leaves,m_sets[0].m_leaves,m_paircache->getNumOverlappingPairs());
|
||||
unsigned int total=m_profiling.m_total;
|
||||
if(total<=0) total=1;
|
||||
printf("ddcollide: %u%% (%uus)\r\n",(50+m_profiling.m_ddcollide*100)/total,m_profiling.m_ddcollide/DBVT_BP_PROFILING_RATE);
|
||||
printf("fdcollide: %u%% (%uus)\r\n",(50+m_profiling.m_fdcollide*100)/total,m_profiling.m_fdcollide/DBVT_BP_PROFILING_RATE);
|
||||
printf("cleanup: %u%% (%uus)\r\n",(50+m_profiling.m_cleanup*100)/total,m_profiling.m_cleanup/DBVT_BP_PROFILING_RATE);
|
||||
printf("total: %uus\r\n",total/DBVT_BP_PROFILING_RATE);
|
||||
const unsigned long sum=m_profiling.m_ddcollide+
|
||||
m_profiling.m_fdcollide+
|
||||
m_profiling.m_cleanup;
|
||||
printf("leaked: %u%% (%uus)\r\n",100-((50+sum*100)/total),(total-sum)/DBVT_BP_PROFILING_RATE);
|
||||
printf("job counts: %u%%\r\n",(m_profiling.m_jobcount*100)/((m_sets[0].m_leaves+m_sets[1].m_leaves)*DBVT_BP_PROFILING_RATE));
|
||||
clear(m_profiling);
|
||||
m_clock.reset();
|
||||
printf("fixed(%u) dynamics(%u) pairs(%u)\r\n",m_sets[1].m_leaves,m_sets[0].m_leaves,m_paircache->getNumOverlappingPairs());
|
||||
unsigned int total=m_profiling.m_total;
|
||||
if(total<=0) total=1;
|
||||
printf("ddcollide: %u%% (%uus)\r\n",(50+m_profiling.m_ddcollide*100)/total,m_profiling.m_ddcollide/DBVT_BP_PROFILING_RATE);
|
||||
printf("fdcollide: %u%% (%uus)\r\n",(50+m_profiling.m_fdcollide*100)/total,m_profiling.m_fdcollide/DBVT_BP_PROFILING_RATE);
|
||||
printf("cleanup: %u%% (%uus)\r\n",(50+m_profiling.m_cleanup*100)/total,m_profiling.m_cleanup/DBVT_BP_PROFILING_RATE);
|
||||
printf("total: %uus\r\n",total/DBVT_BP_PROFILING_RATE);
|
||||
const unsigned long sum=m_profiling.m_ddcollide+
|
||||
m_profiling.m_fdcollide+
|
||||
m_profiling.m_cleanup;
|
||||
printf("leaked: %u%% (%uus)\r\n",100-((50+sum*100)/total),(total-sum)/DBVT_BP_PROFILING_RATE);
|
||||
printf("job counts: %u%%\r\n",(m_profiling.m_jobcount*100)/((m_sets[0].m_leaves+m_sets[1].m_leaves)*DBVT_BP_PROFILING_RATE));
|
||||
clear(m_profiling);
|
||||
m_clock.reset();
|
||||
}
|
||||
#endif
|
||||
|
||||
performDeferredRemoval(dispatcher);
|
||||
|
||||
}
|
||||
|
||||
void btDbvtBroadphase::performDeferredRemoval(btDispatcher* dispatcher)
|
||||
{
|
||||
|
||||
if (m_paircache->hasDeferredRemoval())
|
||||
{
|
||||
|
||||
btBroadphasePairArray& overlappingPairArray = m_paircache->getOverlappingPairArray();
|
||||
|
||||
//perform a sort, to find duplicates and to sort 'invalid' pairs to the end
|
||||
overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
|
||||
|
||||
int 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)
|
||||
{
|
||||
//important to perform AABB check that is consistent with the broadphase
|
||||
btDbvtProxy* pa=(btDbvtProxy*)pair.m_pProxy0;
|
||||
btDbvtProxy* pb=(btDbvtProxy*)pair.m_pProxy1;
|
||||
bool hasOverlap = Intersect(pa->leaf->volume,pb->leaf->volume);
|
||||
|
||||
if (hasOverlap)
|
||||
{
|
||||
needsRemoval = false;
|
||||
} else
|
||||
{
|
||||
needsRemoval = true;
|
||||
}
|
||||
} else
|
||||
{
|
||||
//remove duplicate
|
||||
needsRemoval = true;
|
||||
//should have no algorithm
|
||||
btAssert(!pair.m_algorithm);
|
||||
}
|
||||
|
||||
if (needsRemoval)
|
||||
{
|
||||
m_paircache->cleanOverlappingPair(pair,dispatcher);
|
||||
|
||||
pair.m_pProxy0 = 0;
|
||||
pair.m_pProxy1 = 0;
|
||||
invalidPair++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//perform a sort, to sort 'invalid' pairs to the end
|
||||
overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
|
||||
overlappingPairArray.resize(overlappingPairArray.size() - invalidPair);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void btDbvtBroadphase::collide(btDispatcher* dispatcher)
|
||||
{
|
||||
SPC(m_profiling.m_total);
|
||||
/* optimize */
|
||||
m_sets[0].optimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/100);
|
||||
if(m_fixedleft)
|
||||
/*printf("---------------------------------------------------------\n");
|
||||
printf("m_sets[0].m_leaves=%d\n",m_sets[0].m_leaves);
|
||||
printf("m_sets[1].m_leaves=%d\n",m_sets[1].m_leaves);
|
||||
printf("numPairs = %d\n",getOverlappingPairCache()->getNumOverlappingPairs());
|
||||
{
|
||||
const int count=1+(m_sets[1].m_leaves*m_fupdates)/100;
|
||||
m_sets[1].optimizeIncremental(1+(m_sets[1].m_leaves*m_fupdates)/100);
|
||||
m_fixedleft=btMax<int>(0,m_fixedleft-count);
|
||||
int i;
|
||||
for (i=0;i<getOverlappingPairCache()->getNumOverlappingPairs();i++)
|
||||
{
|
||||
printf("pair[%d]=(%d,%d),",i,getOverlappingPairCache()->getOverlappingPairArray()[i].m_pProxy0->getUid(),
|
||||
getOverlappingPairCache()->getOverlappingPairArray()[i].m_pProxy1->getUid());
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
/* dynamic -> fixed set */
|
||||
m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT;
|
||||
btDbvtProxy* current=m_stageRoots[m_stageCurrent];
|
||||
if(current)
|
||||
*/
|
||||
|
||||
|
||||
|
||||
SPC(m_profiling.m_total);
|
||||
/* optimize */
|
||||
m_sets[0].optimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/100);
|
||||
if(m_fixedleft)
|
||||
{
|
||||
btDbvtTreeCollider collider(this);
|
||||
do {
|
||||
btDbvtProxy* next=current->links[1];
|
||||
listremove(current,m_stageRoots[current->stage]);
|
||||
listappend(current,m_stageRoots[STAGECOUNT]);
|
||||
#if DBVT_BP_ACCURATESLEEPING
|
||||
m_paircache->removeOverlappingPairsContainingProxy(current,dispatcher);
|
||||
collider.proxy=current;
|
||||
btDbvt::collideTV(m_sets[0].m_root,current->aabb,collider);
|
||||
btDbvt::collideTV(m_sets[1].m_root,current->aabb,collider);
|
||||
#endif
|
||||
m_sets[0].remove(current->leaf);
|
||||
current->leaf = m_sets[1].insert(current->aabb,current);
|
||||
current->stage = STAGECOUNT;
|
||||
current = next;
|
||||
const int count=1+(m_sets[1].m_leaves*m_fupdates)/100;
|
||||
m_sets[1].optimizeIncremental(1+(m_sets[1].m_leaves*m_fupdates)/100);
|
||||
m_fixedleft=btMax<int>(0,m_fixedleft-count);
|
||||
}
|
||||
/* dynamic -> fixed set */
|
||||
m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT;
|
||||
btDbvtProxy* current=m_stageRoots[m_stageCurrent];
|
||||
if(current)
|
||||
{
|
||||
btDbvtTreeCollider collider(this);
|
||||
do {
|
||||
btDbvtProxy* next=current->links[1];
|
||||
listremove(current,m_stageRoots[current->stage]);
|
||||
listappend(current,m_stageRoots[STAGECOUNT]);
|
||||
#if DBVT_BP_ACCURATESLEEPING
|
||||
m_paircache->removeOverlappingPairsContainingProxy(current,dispatcher);
|
||||
collider.proxy=current;
|
||||
btDbvt::collideTV(m_sets[0].m_root,current->aabb,collider);
|
||||
btDbvt::collideTV(m_sets[1].m_root,current->aabb,collider);
|
||||
#endif
|
||||
m_sets[0].remove(current->leaf);
|
||||
ATTRIBUTE_ALIGNED16(btDbvtVolume) curAabb=btDbvtVolume::FromMM(current->m_aabbMin,current->m_aabbMax);
|
||||
current->leaf = m_sets[1].insert(curAabb,current);
|
||||
current->stage = STAGECOUNT;
|
||||
current = next;
|
||||
} while(current);
|
||||
m_fixedleft=m_sets[1].m_leaves;
|
||||
m_needcleanup=true;
|
||||
m_fixedleft=m_sets[1].m_leaves;
|
||||
m_needcleanup=true;
|
||||
}
|
||||
/* collide dynamics */
|
||||
/* collide dynamics */
|
||||
{
|
||||
btDbvtTreeCollider collider(this);
|
||||
if(m_deferedcollide)
|
||||
btDbvtTreeCollider collider(this);
|
||||
if(m_deferedcollide)
|
||||
{
|
||||
SPC(m_profiling.m_fdcollide);
|
||||
btDbvt::collideTT(m_sets[0].m_root,m_sets[1].m_root,collider);
|
||||
SPC(m_profiling.m_fdcollide);
|
||||
m_sets[0].collideTTpersistentStack(m_sets[0].m_root,m_sets[1].m_root,collider);
|
||||
}
|
||||
if(m_deferedcollide)
|
||||
if(m_deferedcollide)
|
||||
{
|
||||
SPC(m_profiling.m_ddcollide);
|
||||
btDbvt::collideTT(m_sets[0].m_root,m_sets[0].m_root,collider);
|
||||
SPC(m_profiling.m_ddcollide);
|
||||
m_sets[0].collideTTpersistentStack(m_sets[0].m_root,m_sets[0].m_root,collider);
|
||||
}
|
||||
}
|
||||
/* clean up */
|
||||
if(m_needcleanup)
|
||||
/* clean up */
|
||||
if(m_needcleanup)
|
||||
{
|
||||
SPC(m_profiling.m_cleanup);
|
||||
btBroadphasePairArray& pairs=m_paircache->getOverlappingPairArray();
|
||||
if(pairs.size()>0)
|
||||
SPC(m_profiling.m_cleanup);
|
||||
btBroadphasePairArray& pairs=m_paircache->getOverlappingPairArray();
|
||||
if(pairs.size()>0)
|
||||
{
|
||||
const int ci=pairs.size();
|
||||
int ni=btMin(ci,btMax<int>(m_newpairs,(ci*m_cupdates)/100));
|
||||
for(int i=0;i<ni;++i)
|
||||
|
||||
int ni=btMin(pairs.size(),btMax<int>(m_newpairs,(pairs.size()*m_cupdates)/100));
|
||||
for(int i=0;i<ni;++i)
|
||||
{
|
||||
btBroadphasePair& p=pairs[(m_cid+i)%ci];
|
||||
btDbvtProxy* pa=(btDbvtProxy*)p.m_pProxy0;
|
||||
btDbvtProxy* pb=(btDbvtProxy*)p.m_pProxy1;
|
||||
if(!Intersect(pa->leaf->volume,pb->leaf->volume))
|
||||
btBroadphasePair& p=pairs[(m_cid+i)%pairs.size()];
|
||||
btDbvtProxy* pa=(btDbvtProxy*)p.m_pProxy0;
|
||||
btDbvtProxy* pb=(btDbvtProxy*)p.m_pProxy1;
|
||||
if(!Intersect(pa->leaf->volume,pb->leaf->volume))
|
||||
{
|
||||
#if DBVT_BP_SORTPAIRS
|
||||
if(pa>pb) btSwap(pa,pb);
|
||||
#endif
|
||||
m_paircache->removeOverlappingPair(pa,pb,dispatcher);
|
||||
--ni;--i;
|
||||
#if DBVT_BP_SORTPAIRS
|
||||
if(pa->m_uniqueId>pb->m_uniqueId)
|
||||
btSwap(pa,pb);
|
||||
#endif
|
||||
m_paircache->removeOverlappingPair(pa,pb,dispatcher);
|
||||
--ni;--i;
|
||||
}
|
||||
}
|
||||
if(pairs.size()>0) m_cid=(m_cid+ni)%pairs.size(); else m_cid=0;
|
||||
if(pairs.size()>0) m_cid=(m_cid+ni)%pairs.size(); else m_cid=0;
|
||||
}
|
||||
}
|
||||
++m_pid;
|
||||
m_newpairs=1;
|
||||
m_needcleanup=false;
|
||||
if(m_updates_call>0)
|
||||
++m_pid;
|
||||
m_newpairs=1;
|
||||
m_needcleanup=false;
|
||||
if(m_updates_call>0)
|
||||
{ m_updates_ratio=m_updates_done/(btScalar)m_updates_call; }
|
||||
else
|
||||
{ m_updates_ratio=0; }
|
||||
m_updates_done/=2;
|
||||
m_updates_call/=2;
|
||||
m_updates_done/=2;
|
||||
m_updates_call/=2;
|
||||
}
|
||||
|
||||
//
|
||||
void btDbvtBroadphase::optimize()
|
||||
{
|
||||
m_sets[0].optimizeTopDown();
|
||||
m_sets[1].optimizeTopDown();
|
||||
m_sets[0].optimizeTopDown();
|
||||
m_sets[1].optimizeTopDown();
|
||||
}
|
||||
|
||||
//
|
||||
btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache()
|
||||
{
|
||||
return(m_paircache);
|
||||
return(m_paircache);
|
||||
}
|
||||
|
||||
//
|
||||
const btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() const
|
||||
{
|
||||
return(m_paircache);
|
||||
return(m_paircache);
|
||||
}
|
||||
|
||||
//
|
||||
@ -402,16 +547,49 @@ void btDbvtBroadphase::getBroadphaseAabb(btVector3& aabbMin,btVector3& aab
|
||||
|
||||
ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds;
|
||||
|
||||
if(!m_sets[0].empty())
|
||||
if(!m_sets[1].empty()) Merge( m_sets[0].m_root->volume,
|
||||
m_sets[1].m_root->volume,bounds);
|
||||
else
|
||||
bounds=m_sets[0].m_root->volume;
|
||||
else if(!m_sets[1].empty()) bounds=m_sets[1].m_root->volume;
|
||||
else
|
||||
bounds=btDbvtVolume::FromCR(btVector3(0,0,0),0);
|
||||
aabbMin=bounds.Mins();
|
||||
aabbMax=bounds.Maxs();
|
||||
if(!m_sets[0].empty())
|
||||
if(!m_sets[1].empty()) Merge( m_sets[0].m_root->volume,
|
||||
m_sets[1].m_root->volume,bounds);
|
||||
else
|
||||
bounds=m_sets[0].m_root->volume;
|
||||
else if(!m_sets[1].empty()) bounds=m_sets[1].m_root->volume;
|
||||
else
|
||||
bounds=btDbvtVolume::FromCR(btVector3(0,0,0),0);
|
||||
aabbMin=bounds.Mins();
|
||||
aabbMax=bounds.Maxs();
|
||||
}
|
||||
|
||||
void btDbvtBroadphase::resetPool(btDispatcher* dispatcher)
|
||||
{
|
||||
|
||||
int totalObjects = m_sets[0].m_leaves + m_sets[1].m_leaves;
|
||||
if (!totalObjects)
|
||||
{
|
||||
//reset internal dynamic tree data structures
|
||||
m_sets[0].clear();
|
||||
m_sets[1].clear();
|
||||
|
||||
m_deferedcollide = false;
|
||||
m_needcleanup = true;
|
||||
m_prediction = 1/(btScalar)2;
|
||||
m_stageCurrent = 0;
|
||||
m_fixedleft = 0;
|
||||
m_fupdates = 1;
|
||||
m_dupdates = 0;
|
||||
m_cupdates = 10;
|
||||
m_newpairs = 1;
|
||||
m_updates_call = 0;
|
||||
m_updates_done = 0;
|
||||
m_updates_ratio = 0;
|
||||
|
||||
m_gid = 0;
|
||||
m_pid = 0;
|
||||
m_cid = 0;
|
||||
for(int i=0;i<=STAGECOUNT;++i)
|
||||
{
|
||||
m_stageRoots[i]=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
@ -422,9 +600,9 @@ void btDbvtBroadphase::printStats()
|
||||
#if DBVT_BP_ENABLE_BENCHMARK
|
||||
|
||||
struct btBroadphaseBenchmark
|
||||
{
|
||||
{
|
||||
struct Experiment
|
||||
{
|
||||
{
|
||||
const char* name;
|
||||
int object_count;
|
||||
int update_count;
|
||||
@ -432,109 +610,109 @@ struct btBroadphaseBenchmark
|
||||
int iterations;
|
||||
btScalar speed;
|
||||
btScalar amplitude;
|
||||
};
|
||||
};
|
||||
struct Object
|
||||
{
|
||||
{
|
||||
btVector3 center;
|
||||
btVector3 extents;
|
||||
btBroadphaseProxy* proxy;
|
||||
btScalar time;
|
||||
void update(btScalar speed,btScalar amplitude,btBroadphaseInterface* pbi)
|
||||
{
|
||||
{
|
||||
time += speed;
|
||||
center[0] = btCos(time*(btScalar)2.17)*amplitude+
|
||||
btSin(time)*amplitude/2;
|
||||
btSin(time)*amplitude/2;
|
||||
center[1] = btCos(time*(btScalar)1.38)*amplitude+
|
||||
btSin(time)*amplitude;
|
||||
btSin(time)*amplitude;
|
||||
center[2] = btSin(time*(btScalar)0.777)*amplitude;
|
||||
pbi->setAabb(proxy,center-extents,center+extents,0);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
static int UnsignedRand(int range=RAND_MAX-1) { return(rand()%(range+1)); }
|
||||
static btScalar UnitRand() { return(UnsignedRand(16384)/(btScalar)16384); }
|
||||
static void OutputTime(const char* name,btClock& c,unsigned count=0)
|
||||
{
|
||||
{
|
||||
const unsigned long us=c.getTimeMicroseconds();
|
||||
const unsigned long ms=(us+500)/1000;
|
||||
const btScalar sec=us/(btScalar)(1000*1000);
|
||||
if(count>0)
|
||||
printf("%s : %u us (%u ms), %.2f/s\r\n",name,us,ms,count/sec);
|
||||
else
|
||||
else
|
||||
printf("%s : %u us (%u ms)\r\n",name,us,ms);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
void btDbvtBroadphase::benchmark(btBroadphaseInterface* pbi)
|
||||
{
|
||||
static const btBroadphaseBenchmark::Experiment experiments[]=
|
||||
static const btBroadphaseBenchmark::Experiment experiments[]=
|
||||
{
|
||||
{"1024o.10%",1024,10,0,8192,(btScalar)0.005,(btScalar)100},
|
||||
/*{"4096o.10%",4096,10,0,8192,(btScalar)0.005,(btScalar)100},
|
||||
{"8192o.10%",8192,10,0,8192,(btScalar)0.005,(btScalar)100},*/
|
||||
{"1024o.10%",1024,10,0,8192,(btScalar)0.005,(btScalar)100},
|
||||
/*{"4096o.10%",4096,10,0,8192,(btScalar)0.005,(btScalar)100},
|
||||
{"8192o.10%",8192,10,0,8192,(btScalar)0.005,(btScalar)100},*/
|
||||
};
|
||||
static const int nexperiments=sizeof(experiments)/sizeof(experiments[0]);
|
||||
btAlignedObjectArray<btBroadphaseBenchmark::Object*> objects;
|
||||
btClock wallclock;
|
||||
/* Begin */
|
||||
for(int iexp=0;iexp<nexperiments;++iexp)
|
||||
static const int nexperiments=sizeof(experiments)/sizeof(experiments[0]);
|
||||
btAlignedObjectArray<btBroadphaseBenchmark::Object*> objects;
|
||||
btClock wallclock;
|
||||
/* Begin */
|
||||
for(int iexp=0;iexp<nexperiments;++iexp)
|
||||
{
|
||||
const btBroadphaseBenchmark::Experiment& experiment=experiments[iexp];
|
||||
const int object_count=experiment.object_count;
|
||||
const int update_count=(object_count*experiment.update_count)/100;
|
||||
const int spawn_count=(object_count*experiment.spawn_count)/100;
|
||||
const btScalar speed=experiment.speed;
|
||||
const btScalar amplitude=experiment.amplitude;
|
||||
printf("Experiment #%u '%s':\r\n",iexp,experiment.name);
|
||||
printf("\tObjects: %u\r\n",object_count);
|
||||
printf("\tUpdate: %u\r\n",update_count);
|
||||
printf("\tSpawn: %u\r\n",spawn_count);
|
||||
printf("\tSpeed: %f\r\n",speed);
|
||||
printf("\tAmplitude: %f\r\n",amplitude);
|
||||
srand(180673);
|
||||
/* Create objects */
|
||||
wallclock.reset();
|
||||
objects.reserve(object_count);
|
||||
for(int i=0;i<object_count;++i)
|
||||
const btBroadphaseBenchmark::Experiment& experiment=experiments[iexp];
|
||||
const int object_count=experiment.object_count;
|
||||
const int update_count=(object_count*experiment.update_count)/100;
|
||||
const int spawn_count=(object_count*experiment.spawn_count)/100;
|
||||
const btScalar speed=experiment.speed;
|
||||
const btScalar amplitude=experiment.amplitude;
|
||||
printf("Experiment #%u '%s':\r\n",iexp,experiment.name);
|
||||
printf("\tObjects: %u\r\n",object_count);
|
||||
printf("\tUpdate: %u\r\n",update_count);
|
||||
printf("\tSpawn: %u\r\n",spawn_count);
|
||||
printf("\tSpeed: %f\r\n",speed);
|
||||
printf("\tAmplitude: %f\r\n",amplitude);
|
||||
srand(180673);
|
||||
/* Create objects */
|
||||
wallclock.reset();
|
||||
objects.reserve(object_count);
|
||||
for(int i=0;i<object_count;++i)
|
||||
{
|
||||
btBroadphaseBenchmark::Object* po=new btBroadphaseBenchmark::Object();
|
||||
po->center[0]=btBroadphaseBenchmark::UnitRand()*50;
|
||||
po->center[1]=btBroadphaseBenchmark::UnitRand()*50;
|
||||
po->center[2]=btBroadphaseBenchmark::UnitRand()*50;
|
||||
po->extents[0]=btBroadphaseBenchmark::UnitRand()*2+2;
|
||||
po->extents[1]=btBroadphaseBenchmark::UnitRand()*2+2;
|
||||
po->extents[2]=btBroadphaseBenchmark::UnitRand()*2+2;
|
||||
po->time=btBroadphaseBenchmark::UnitRand()*2000;
|
||||
po->proxy=pbi->createProxy(po->center-po->extents,po->center+po->extents,0,po,1,1,0,0);
|
||||
objects.push_back(po);
|
||||
btBroadphaseBenchmark::Object* po=new btBroadphaseBenchmark::Object();
|
||||
po->center[0]=btBroadphaseBenchmark::UnitRand()*50;
|
||||
po->center[1]=btBroadphaseBenchmark::UnitRand()*50;
|
||||
po->center[2]=btBroadphaseBenchmark::UnitRand()*50;
|
||||
po->extents[0]=btBroadphaseBenchmark::UnitRand()*2+2;
|
||||
po->extents[1]=btBroadphaseBenchmark::UnitRand()*2+2;
|
||||
po->extents[2]=btBroadphaseBenchmark::UnitRand()*2+2;
|
||||
po->time=btBroadphaseBenchmark::UnitRand()*2000;
|
||||
po->proxy=pbi->createProxy(po->center-po->extents,po->center+po->extents,0,po,1,1,0,0);
|
||||
objects.push_back(po);
|
||||
}
|
||||
btBroadphaseBenchmark::OutputTime("\tInitialization",wallclock);
|
||||
/* First update */
|
||||
wallclock.reset();
|
||||
for(int i=0;i<objects.size();++i)
|
||||
btBroadphaseBenchmark::OutputTime("\tInitialization",wallclock);
|
||||
/* First update */
|
||||
wallclock.reset();
|
||||
for(int i=0;i<objects.size();++i)
|
||||
{
|
||||
objects[i]->update(speed,amplitude,pbi);
|
||||
objects[i]->update(speed,amplitude,pbi);
|
||||
}
|
||||
btBroadphaseBenchmark::OutputTime("\tFirst update",wallclock);
|
||||
/* Updates */
|
||||
wallclock.reset();
|
||||
for(int i=0;i<experiment.iterations;++i)
|
||||
btBroadphaseBenchmark::OutputTime("\tFirst update",wallclock);
|
||||
/* Updates */
|
||||
wallclock.reset();
|
||||
for(int i=0;i<experiment.iterations;++i)
|
||||
{
|
||||
for(int j=0;j<update_count;++j)
|
||||
for(int j=0;j<update_count;++j)
|
||||
{
|
||||
objects[j]->update(speed,amplitude,pbi);
|
||||
objects[j]->update(speed,amplitude,pbi);
|
||||
}
|
||||
pbi->calculateOverlappingPairs(0);
|
||||
pbi->calculateOverlappingPairs(0);
|
||||
}
|
||||
btBroadphaseBenchmark::OutputTime("\tUpdate",wallclock,experiment.iterations);
|
||||
/* Clean up */
|
||||
wallclock.reset();
|
||||
for(int i=0;i<objects.size();++i)
|
||||
btBroadphaseBenchmark::OutputTime("\tUpdate",wallclock,experiment.iterations);
|
||||
/* Clean up */
|
||||
wallclock.reset();
|
||||
for(int i=0;i<objects.size();++i)
|
||||
{
|
||||
pbi->destroyProxy(objects[i]->proxy,0);
|
||||
delete objects[i];
|
||||
pbi->destroyProxy(objects[i]->proxy,0);
|
||||
delete objects[i];
|
||||
}
|
||||
objects.resize(0);
|
||||
btBroadphaseBenchmark::OutputTime("\tRelease",wallclock);
|
||||
objects.resize(0);
|
||||
btBroadphaseBenchmark::OutputTime("\tRelease",wallclock);
|
||||
}
|
||||
|
||||
}
|
||||
@ -546,3 +724,4 @@ void btDbvtBroadphase::benchmark(btBroadphaseInterface*)
|
||||
#if DBVT_BP_PROFILE
|
||||
#undef SPC
|
||||
#endif
|
||||
|
||||
|
@ -24,15 +24,15 @@ subject to the following restrictions:
|
||||
//
|
||||
|
||||
#define DBVT_BP_PROFILE 0
|
||||
#define DBVT_BP_SORTPAIRS 1
|
||||
//#define DBVT_BP_SORTPAIRS 1
|
||||
#define DBVT_BP_PREVENTFALSEUPDATE 0
|
||||
#define DBVT_BP_ACCURATESLEEPING 0
|
||||
#define DBVT_BP_ENABLE_BENCHMARK 0
|
||||
#define DBVT_BP_MARGIN (btScalar)0.05
|
||||
|
||||
#if DBVT_BP_PROFILE
|
||||
#define DBVT_BP_PROFILING_RATE 256
|
||||
#include "LinearMath/btQuickprof.h"
|
||||
#define DBVT_BP_PROFILING_RATE 256
|
||||
#include "LinearMath/btQuickprof.h"
|
||||
#endif
|
||||
|
||||
//
|
||||
@ -40,16 +40,16 @@ subject to the following restrictions:
|
||||
//
|
||||
struct btDbvtProxy : btBroadphaseProxy
|
||||
{
|
||||
/* Fields */
|
||||
btDbvtAabbMm aabb;
|
||||
btDbvtNode* leaf;
|
||||
btDbvtProxy* links[2];
|
||||
int stage;
|
||||
/* ctor */
|
||||
btDbvtProxy(void* userPtr,short int collisionFilterGroup, short int collisionFilterMask) :
|
||||
btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask)
|
||||
/* Fields */
|
||||
//btDbvtAabbMm aabb;
|
||||
btDbvtNode* leaf;
|
||||
btDbvtProxy* links[2];
|
||||
int stage;
|
||||
/* ctor */
|
||||
btDbvtProxy(const btVector3& aabbMin,const btVector3& aabbMax,void* userPtr,short int collisionFilterGroup, short int collisionFilterMask) :
|
||||
btBroadphaseProxy(aabbMin,aabbMax,userPtr,collisionFilterGroup,collisionFilterMask)
|
||||
{
|
||||
links[0]=links[1]=0;
|
||||
links[0]=links[1]=0;
|
||||
}
|
||||
};
|
||||
|
||||
@ -60,57 +60,67 @@ typedef btAlignedObjectArray<btDbvtProxy*> btDbvtProxyArray;
|
||||
///This is a very fast broadphase, especially for very dynamic worlds where many objects are moving. Its insert/add and remove of objects is generally faster than the sweep and prune broadphases btAxisSweep3 and bt32BitAxisSweep3.
|
||||
struct btDbvtBroadphase : btBroadphaseInterface
|
||||
{
|
||||
/* Config */
|
||||
enum {
|
||||
/* Config */
|
||||
enum {
|
||||
DYNAMIC_SET = 0, /* Dynamic set index */
|
||||
FIXED_SET = 1, /* Fixed set index */
|
||||
STAGECOUNT = 2 /* Number of stages */
|
||||
};
|
||||
/* Fields */
|
||||
btDbvt m_sets[2]; // Dbvt sets
|
||||
btDbvtProxy* m_stageRoots[STAGECOUNT+1]; // Stages list
|
||||
btOverlappingPairCache* m_paircache; // Pair cache
|
||||
btScalar m_prediction; // Velocity prediction
|
||||
int m_stageCurrent; // Current stage
|
||||
int m_fupdates; // % of fixed updates per frame
|
||||
int m_dupdates; // % of dynamic updates per frame
|
||||
int m_cupdates; // % of cleanup updates per frame
|
||||
int m_newpairs; // Number of pairs created
|
||||
int m_fixedleft; // Fixed optimization left
|
||||
unsigned m_updates_call; // Number of updates call
|
||||
unsigned m_updates_done; // Number of updates done
|
||||
btScalar m_updates_ratio; // m_updates_done/m_updates_call
|
||||
int m_pid; // Parse id
|
||||
int m_cid; // Cleanup index
|
||||
int m_gid; // Gen id
|
||||
bool m_releasepaircache; // Release pair cache on delete
|
||||
bool m_deferedcollide; // Defere dynamic/static collision to collide call
|
||||
bool m_needcleanup; // Need to run cleanup?
|
||||
};
|
||||
/* Fields */
|
||||
btDbvt m_sets[2]; // Dbvt sets
|
||||
btDbvtProxy* m_stageRoots[STAGECOUNT+1]; // Stages list
|
||||
btOverlappingPairCache* m_paircache; // Pair cache
|
||||
btScalar m_prediction; // Velocity prediction
|
||||
int m_stageCurrent; // Current stage
|
||||
int m_fupdates; // % of fixed updates per frame
|
||||
int m_dupdates; // % of dynamic updates per frame
|
||||
int m_cupdates; // % of cleanup updates per frame
|
||||
int m_newpairs; // Number of pairs created
|
||||
int m_fixedleft; // Fixed optimization left
|
||||
unsigned m_updates_call; // Number of updates call
|
||||
unsigned m_updates_done; // Number of updates done
|
||||
btScalar m_updates_ratio; // m_updates_done/m_updates_call
|
||||
int m_pid; // Parse id
|
||||
int m_cid; // Cleanup index
|
||||
int m_gid; // Gen id
|
||||
bool m_releasepaircache; // Release pair cache on delete
|
||||
bool m_deferedcollide; // Defere dynamic/static collision to collide call
|
||||
bool m_needcleanup; // Need to run cleanup?
|
||||
#if DBVT_BP_PROFILE
|
||||
btClock m_clock;
|
||||
struct {
|
||||
btClock m_clock;
|
||||
struct {
|
||||
unsigned long m_total;
|
||||
unsigned long m_ddcollide;
|
||||
unsigned long m_fdcollide;
|
||||
unsigned long m_cleanup;
|
||||
unsigned long m_jobcount;
|
||||
} m_profiling;
|
||||
} m_profiling;
|
||||
#endif
|
||||
/* Methods */
|
||||
btDbvtBroadphase(btOverlappingPairCache* paircache=0);
|
||||
~btDbvtBroadphase();
|
||||
void collide(btDispatcher* dispatcher);
|
||||
void optimize();
|
||||
/* btBroadphaseInterface Implementation */
|
||||
btBroadphaseProxy* createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
|
||||
void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
|
||||
void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
|
||||
void calculateOverlappingPairs(btDispatcher* dispatcher);
|
||||
btOverlappingPairCache* getOverlappingPairCache();
|
||||
const btOverlappingPairCache* getOverlappingPairCache() const;
|
||||
void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const;
|
||||
void printStats();
|
||||
static void benchmark(btBroadphaseInterface*);
|
||||
/* Methods */
|
||||
btDbvtBroadphase(btOverlappingPairCache* paircache=0);
|
||||
~btDbvtBroadphase();
|
||||
void collide(btDispatcher* dispatcher);
|
||||
void optimize();
|
||||
/* btBroadphaseInterface Implementation */
|
||||
btBroadphaseProxy* createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
|
||||
void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
|
||||
void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
|
||||
virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0));
|
||||
|
||||
virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
|
||||
void calculateOverlappingPairs(btDispatcher* dispatcher);
|
||||
btOverlappingPairCache* getOverlappingPairCache();
|
||||
const btOverlappingPairCache* getOverlappingPairCache() const;
|
||||
void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const;
|
||||
void printStats();
|
||||
static void benchmark(btBroadphaseInterface*);
|
||||
|
||||
|
||||
void performDeferredRemoval(btDispatcher* dispatcher);
|
||||
|
||||
///reset broadphase internal structures, to ensure determinism/reproducability
|
||||
virtual void resetPool(btDispatcher* dispatcher);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -46,22 +46,25 @@ struct btDispatcherInfo
|
||||
m_enableSPU(true),
|
||||
m_useEpa(true),
|
||||
m_allowedCcdPenetration(btScalar(0.04)),
|
||||
m_useConvexConservativeDistanceUtil(true),
|
||||
m_convexConservativeDistanceThreshold(0.0f),
|
||||
m_stackAllocator(0)
|
||||
{
|
||||
|
||||
}
|
||||
btScalar m_timeStep;
|
||||
int m_stepCount;
|
||||
int m_dispatchFunc;
|
||||
int m_stepCount;
|
||||
int m_dispatchFunc;
|
||||
mutable btScalar m_timeOfImpact;
|
||||
bool m_useContinuous;
|
||||
bool m_useContinuous;
|
||||
class btIDebugDraw* m_debugDraw;
|
||||
bool m_enableSatConvex;
|
||||
bool m_enableSPU;
|
||||
bool m_useEpa;
|
||||
bool m_enableSatConvex;
|
||||
bool m_enableSPU;
|
||||
bool m_useEpa;
|
||||
btScalar m_allowedCcdPenetration;
|
||||
bool m_useConvexConservativeDistanceUtil;
|
||||
btScalar m_convexConservativeDistanceThreshold;
|
||||
btStackAlloc* m_stackAllocator;
|
||||
|
||||
};
|
||||
|
||||
///The btDispatcher interface class can be used in combination with broadphase to dispatch calculations for overlapping pairs.
|
||||
|
@ -149,6 +149,22 @@ amin.getZ() >= bmin.getZ() && amax.getZ() <= bmax.getZ();
|
||||
|
||||
|
||||
|
||||
void btMultiSapBroadphase::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const
|
||||
{
|
||||
btMultiSapProxy* multiProxy = static_cast<btMultiSapProxy*>(proxy);
|
||||
aabbMin = multiProxy->m_aabbMin;
|
||||
aabbMax = multiProxy->m_aabbMax;
|
||||
}
|
||||
|
||||
void btMultiSapBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin,const btVector3& aabbMax)
|
||||
{
|
||||
for (int i=0;i<m_multiSapProxies.size();i++)
|
||||
{
|
||||
rayCallback.process(m_multiSapProxies[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//#include <stdio.h>
|
||||
|
||||
void btMultiSapBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)
|
||||
@ -208,7 +224,9 @@ void btMultiSapBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aab
|
||||
|
||||
|
||||
|
||||
m_optimizedAabbTree->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax);
|
||||
if (m_optimizedAabbTree)
|
||||
m_optimizedAabbTree->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax);
|
||||
|
||||
int i;
|
||||
|
||||
for ( i=0;i<multiProxy->m_bridgeProxies.size();i++)
|
||||
@ -464,3 +482,8 @@ void btMultiSapBroadphase::printStats()
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
void btMultiSapBroadphase::resetPool(btDispatcher* dispatcher)
|
||||
{
|
||||
// not yet
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ class btSimpleBroadphase;
|
||||
|
||||
typedef btAlignedObjectArray<btBroadphaseInterface*> btSapBroadphaseArray;
|
||||
|
||||
///The btMultiSapBroadphase is a research project, not recommended to use in production. Use btAxisSweep3 or btDbvtBroadphase instead.
|
||||
///The btMultiSapBroadphase is a broadphase that contains multiple SAP broadphases.
|
||||
///The user can add SAP broadphases that cover the world. A btBroadphaseProxy can be in multiple child broadphases at the same time.
|
||||
///A btQuantizedBvh acceleration structures finds overlapping SAPs for each btBroadphaseProxy.
|
||||
@ -72,7 +73,7 @@ public:
|
||||
short int m_collisionFilterMask;
|
||||
*/
|
||||
btMultiSapProxy(const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask)
|
||||
:btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask),
|
||||
:btBroadphaseProxy(aabbMin,aabbMax,userPtr,collisionFilterGroup,collisionFilterMask),
|
||||
m_aabbMin(aabbMin),
|
||||
m_aabbMax(aabbMax),
|
||||
m_shapeType(shapeType)
|
||||
@ -108,6 +109,9 @@ public:
|
||||
virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy);
|
||||
virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
|
||||
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher);
|
||||
virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
|
||||
|
||||
virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin=btVector3(0,0,0),const btVector3& aabbMax=btVector3(0,0,0));
|
||||
|
||||
void addToChildBroadphase(btMultiSapProxy* parentMultiSapProxy, btBroadphaseProxy* childProxy, btBroadphaseInterface* childBroadphase);
|
||||
|
||||
@ -139,6 +143,9 @@ public:
|
||||
|
||||
void quicksort (btBroadphasePairArray& a, int lo, int hi);
|
||||
|
||||
///reset broadphase internal structures, to ensure determinism/reproducability
|
||||
virtual void resetPool(btDispatcher* dispatcher);
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_MULTI_SAP_BROADPHASE
|
||||
|
@ -19,6 +19,7 @@ subject to the following restrictions:
|
||||
|
||||
#include "btDispatcher.h"
|
||||
#include "btCollisionAlgorithm.h"
|
||||
#include "LinearMath/btAabbUtil2.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@ -33,7 +34,8 @@ int gFindPairs =0;
|
||||
|
||||
btHashedOverlappingPairCache::btHashedOverlappingPairCache():
|
||||
m_overlapFilterCallback(0),
|
||||
m_blockedForChanges(false)
|
||||
m_blockedForChanges(false),
|
||||
m_ghostPairCallback(0)
|
||||
{
|
||||
int initialAllocatedSize= 2;
|
||||
m_overlappingPairArray.reserve(initialAllocatedSize);
|
||||
@ -45,7 +47,6 @@ btHashedOverlappingPairCache::btHashedOverlappingPairCache():
|
||||
|
||||
btHashedOverlappingPairCache::~btHashedOverlappingPairCache()
|
||||
{
|
||||
//todo/test: show we erase/delete data, or is it automatic
|
||||
}
|
||||
|
||||
|
||||
@ -135,7 +136,8 @@ void btHashedOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroad
|
||||
btBroadphasePair* btHashedOverlappingPairCache::findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1)
|
||||
{
|
||||
gFindPairs++;
|
||||
if(proxy0>proxy1) btSwap(proxy0,proxy1);
|
||||
if(proxy0->m_uniqueId>proxy1->m_uniqueId)
|
||||
btSwap(proxy0,proxy1);
|
||||
int proxyId1 = proxy0->getUid();
|
||||
int proxyId2 = proxy1->getUid();
|
||||
|
||||
@ -211,7 +213,8 @@ void btHashedOverlappingPairCache::growTables()
|
||||
|
||||
btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1)
|
||||
{
|
||||
if(proxy0>proxy1) btSwap(proxy0,proxy1);
|
||||
if(proxy0->m_uniqueId>proxy1->m_uniqueId)
|
||||
btSwap(proxy0,proxy1);
|
||||
int proxyId1 = proxy0->getUid();
|
||||
int proxyId2 = proxy1->getUid();
|
||||
|
||||
@ -238,6 +241,11 @@ btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProx
|
||||
int count = m_overlappingPairArray.size();
|
||||
int oldCapacity = m_overlappingPairArray.capacity();
|
||||
void* mem = &m_overlappingPairArray.expand();
|
||||
|
||||
//this is where we add an actual pair, so also call the 'ghost'
|
||||
if (m_ghostPairCallback)
|
||||
m_ghostPairCallback->addOverlappingPair(proxy0,proxy1);
|
||||
|
||||
int newCapacity = m_overlappingPairArray.capacity();
|
||||
|
||||
if (oldCapacity < newCapacity)
|
||||
@ -251,7 +259,7 @@ btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProx
|
||||
// pair->m_pProxy0 = proxy0;
|
||||
// pair->m_pProxy1 = proxy1;
|
||||
pair->m_algorithm = 0;
|
||||
pair->m_userInfo = 0;
|
||||
pair->m_internalTmpValue = 0;
|
||||
|
||||
|
||||
m_next[count] = m_hashTable[hash];
|
||||
@ -265,7 +273,8 @@ btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProx
|
||||
void* btHashedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1,btDispatcher* dispatcher)
|
||||
{
|
||||
gRemovePairs++;
|
||||
if(proxy0>proxy1) btSwap(proxy0,proxy1);
|
||||
if(proxy0->m_uniqueId>proxy1->m_uniqueId)
|
||||
btSwap(proxy0,proxy1);
|
||||
int proxyId1 = proxy0->getUid();
|
||||
int proxyId2 = proxy1->getUid();
|
||||
|
||||
@ -282,7 +291,7 @@ void* btHashedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* pro
|
||||
|
||||
cleanOverlappingPair(*pair,dispatcher);
|
||||
|
||||
void* userData = pair->m_userInfo;
|
||||
void* userData = pair->m_internalInfo1;
|
||||
|
||||
btAssert(pair->m_pProxy0->getUid() == proxyId1);
|
||||
btAssert(pair->m_pProxy1->getUid() == proxyId2);
|
||||
@ -317,6 +326,9 @@ void* btHashedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* pro
|
||||
|
||||
int lastPairIndex = m_overlappingPairArray.size() - 1;
|
||||
|
||||
if (m_ghostPairCallback)
|
||||
m_ghostPairCallback->removeOverlappingPair(proxy0, proxy1,dispatcher);
|
||||
|
||||
// If the removed pair is the last pair, we are done.
|
||||
if (lastPairIndex == pairIndex)
|
||||
{
|
||||
@ -384,6 +396,35 @@ void btHashedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback*
|
||||
}
|
||||
}
|
||||
|
||||
void btHashedOverlappingPairCache::sortOverlappingPairs(btDispatcher* dispatcher)
|
||||
{
|
||||
///need to keep hashmap in sync with pair address, so rebuild all
|
||||
btBroadphasePairArray tmpPairs;
|
||||
int i;
|
||||
for (i=0;i<m_overlappingPairArray.size();i++)
|
||||
{
|
||||
tmpPairs.push_back(m_overlappingPairArray[i]);
|
||||
}
|
||||
|
||||
for (i=0;i<tmpPairs.size();i++)
|
||||
{
|
||||
removeOverlappingPair(tmpPairs[i].m_pProxy0,tmpPairs[i].m_pProxy1,dispatcher);
|
||||
}
|
||||
|
||||
for (i = 0; i < m_next.size(); i++)
|
||||
{
|
||||
m_next[i] = BT_NULL_PAIR;
|
||||
}
|
||||
|
||||
tmpPairs.quickSort(btBroadphasePairSortPredicate());
|
||||
|
||||
for (i=0;i<tmpPairs.size();i++)
|
||||
{
|
||||
addOverlappingPair(tmpPairs[i].m_pProxy0,tmpPairs[i].m_pProxy1);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void* btSortedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1, btDispatcher* dispatcher )
|
||||
@ -397,8 +438,10 @@ void* btSortedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* pro
|
||||
{
|
||||
gOverlappingPairs--;
|
||||
btBroadphasePair& pair = m_overlappingPairArray[findIndex];
|
||||
void* userData = pair.m_userInfo;
|
||||
void* userData = pair.m_internalInfo1;
|
||||
cleanOverlappingPair(pair,dispatcher);
|
||||
if (m_ghostPairCallback)
|
||||
m_ghostPairCallback->removeOverlappingPair(proxy0, proxy1,dispatcher);
|
||||
|
||||
m_overlappingPairArray.swap(findIndex,m_overlappingPairArray.capacity()-1);
|
||||
m_overlappingPairArray.pop_back();
|
||||
@ -419,15 +462,19 @@ void* btSortedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* pro
|
||||
btBroadphasePair* btSortedOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
|
||||
{
|
||||
//don't add overlap with own
|
||||
assert(proxy0 != proxy1);
|
||||
btAssert(proxy0 != proxy1);
|
||||
|
||||
if (!needsBroadphaseCollision(proxy0,proxy1))
|
||||
return 0;
|
||||
|
||||
void* mem = &m_overlappingPairArray.expand();
|
||||
btBroadphasePair* pair = new (mem) btBroadphasePair(*proxy0,*proxy1);
|
||||
|
||||
gOverlappingPairs++;
|
||||
gAddedPairs++;
|
||||
|
||||
if (m_ghostPairCallback)
|
||||
m_ghostPairCallback->addOverlappingPair(proxy0, proxy1);
|
||||
return pair;
|
||||
|
||||
}
|
||||
@ -446,7 +493,7 @@ btBroadphasePair* btSortedOverlappingPairCache::addOverlappingPair(btBroadphaseP
|
||||
|
||||
if (findIndex < m_overlappingPairArray.size())
|
||||
{
|
||||
//assert(it != m_overlappingPairSet.end());
|
||||
//btAssert(it != m_overlappingPairSet.end());
|
||||
btBroadphasePair* pair = &m_overlappingPairArray[findIndex];
|
||||
return pair;
|
||||
}
|
||||
@ -476,8 +523,9 @@ void btSortedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback*
|
||||
if (callback->processOverlap(*pair))
|
||||
{
|
||||
cleanOverlappingPair(*pair,dispatcher);
|
||||
|
||||
m_overlappingPairArray.swap(i,m_overlappingPairArray.capacity()-1);
|
||||
pair->m_pProxy0 = 0;
|
||||
pair->m_pProxy1 = 0;
|
||||
m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
|
||||
m_overlappingPairArray.pop_back();
|
||||
gOverlappingPairs--;
|
||||
} else
|
||||
@ -493,7 +541,8 @@ void btSortedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback*
|
||||
btSortedOverlappingPairCache::btSortedOverlappingPairCache():
|
||||
m_blockedForChanges(false),
|
||||
m_hasDeferredRemoval(true),
|
||||
m_overlapFilterCallback(0)
|
||||
m_overlapFilterCallback(0),
|
||||
m_ghostPairCallback(0)
|
||||
{
|
||||
int initialAllocatedSize= 2;
|
||||
m_overlappingPairArray.reserve(initialAllocatedSize);
|
||||
@ -501,7 +550,6 @@ btSortedOverlappingPairCache::btSortedOverlappingPairCache():
|
||||
|
||||
btSortedOverlappingPairCache::~btSortedOverlappingPairCache()
|
||||
{
|
||||
//todo/test: show we erase/delete data, or is it automatic
|
||||
}
|
||||
|
||||
void btSortedOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher)
|
||||
@ -577,3 +625,9 @@ void btSortedOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroad
|
||||
|
||||
processAllOverlappingPairs(&removeCallback,dispatcher);
|
||||
}
|
||||
|
||||
void btSortedOverlappingPairCache::sortOverlappingPairs(btDispatcher* dispatcher)
|
||||
{
|
||||
//should already be sorted
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,6 @@ subject to the following restrictions:
|
||||
#include "btBroadphaseProxy.h"
|
||||
#include "btOverlappingPairCallback.h"
|
||||
|
||||
#include "LinearMath/btPoint3.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
class btDispatcher;
|
||||
|
||||
@ -83,6 +82,11 @@ public:
|
||||
|
||||
virtual bool hasDeferredRemoval() = 0;
|
||||
|
||||
virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)=0;
|
||||
|
||||
virtual void sortOverlappingPairs(btDispatcher* dispatcher) = 0;
|
||||
|
||||
|
||||
};
|
||||
|
||||
/// Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman, Codercorner, http://codercorner.com
|
||||
@ -253,10 +257,19 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)
|
||||
{
|
||||
m_ghostPairCallback = ghostPairCallback;
|
||||
}
|
||||
|
||||
virtual void sortOverlappingPairs(btDispatcher* dispatcher);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
btAlignedObjectArray<int> m_hashTable;
|
||||
btAlignedObjectArray<int> m_next;
|
||||
btOverlappingPairCallback* m_ghostPairCallback;
|
||||
|
||||
};
|
||||
|
||||
@ -280,6 +293,8 @@ class btSortedOverlappingPairCache : public btOverlappingPairCache
|
||||
//if set, use the callback instead of the built in filter in needBroadphaseCollision
|
||||
btOverlapFilterCallback* m_overlapFilterCallback;
|
||||
|
||||
btOverlappingPairCallback* m_ghostPairCallback;
|
||||
|
||||
public:
|
||||
|
||||
btSortedOverlappingPairCache();
|
||||
@ -355,12 +370,19 @@ class btSortedOverlappingPairCache : public btOverlappingPairCache
|
||||
return m_hasDeferredRemoval;
|
||||
}
|
||||
|
||||
virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)
|
||||
{
|
||||
m_ghostPairCallback = ghostPairCallback;
|
||||
}
|
||||
|
||||
virtual void sortOverlappingPairs(btDispatcher* dispatcher);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
///btNullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and testing.
|
||||
///btNullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and unit testing.
|
||||
class btNullPairCache : public btOverlappingPairCache
|
||||
{
|
||||
|
||||
@ -414,6 +436,11 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void setInternalGhostPairCallback(btOverlappingPairCallback* /* ghostPairCallback */)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/)
|
||||
{
|
||||
return 0;
|
||||
@ -427,6 +454,10 @@ public:
|
||||
virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* /*proxy0*/,btDispatcher* /*dispatcher*/)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void sortOverlappingPairs(btDispatcher* dispatcher)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
@ -18,14 +18,18 @@ subject to the following restrictions:
|
||||
#include "LinearMath/btAabbUtil2.h"
|
||||
#include "LinearMath/btIDebugDraw.h"
|
||||
|
||||
#define RAYAABB2
|
||||
|
||||
btQuantizedBvh::btQuantizedBvh() : m_useQuantization(false),
|
||||
btQuantizedBvh::btQuantizedBvh() :
|
||||
m_bulletVersion(BT_BULLET_VERSION),
|
||||
m_useQuantization(false),
|
||||
//m_traversalMode(TRAVERSAL_STACKLESS_CACHE_FRIENDLY)
|
||||
m_traversalMode(TRAVERSAL_STACKLESS)
|
||||
//m_traversalMode(TRAVERSAL_RECURSIVE)
|
||||
,m_subtreeHeaderCount(0) //PCK: add this line
|
||||
{
|
||||
|
||||
{
|
||||
m_bvhAabbMin.setValue(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY);
|
||||
m_bvhAabbMax.setValue(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY);
|
||||
}
|
||||
|
||||
|
||||
@ -119,7 +123,7 @@ void btQuantizedBvh::buildTree (int startIndex,int endIndex)
|
||||
int numIndices =endIndex-startIndex;
|
||||
int curIndex = m_curNodeIndex;
|
||||
|
||||
assert(numIndices>0);
|
||||
btAssert(numIndices>0);
|
||||
|
||||
if (numIndices==1)
|
||||
{
|
||||
@ -140,8 +144,11 @@ void btQuantizedBvh::buildTree (int startIndex,int endIndex)
|
||||
|
||||
int internalNodeIndex = m_curNodeIndex;
|
||||
|
||||
setInternalNodeAabbMax(m_curNodeIndex,m_bvhAabbMin);
|
||||
setInternalNodeAabbMin(m_curNodeIndex,m_bvhAabbMax);
|
||||
//set the min aabb to 'inf' or a max value, and set the max aabb to a -inf/minimum value.
|
||||
//the aabb will be expanded during buildTree/mergeInternalNodeAabb with actual node values
|
||||
setInternalNodeAabbMin(m_curNodeIndex,m_bvhAabbMax);//can't use btVector3(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY)) because of quantization
|
||||
setInternalNodeAabbMax(m_curNodeIndex,m_bvhAabbMin);//can't use btVector3(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY)) because of quantization
|
||||
|
||||
|
||||
for (i=startIndex;i<endIndex;i++)
|
||||
{
|
||||
@ -177,6 +184,9 @@ void btQuantizedBvh::buildTree (int startIndex,int endIndex)
|
||||
{
|
||||
updateSubtreeHeaders(leftChildNodexIndex,rightChildNodexIndex);
|
||||
}
|
||||
} else
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
setInternalNodeEscapeIndex(internalNodeIndex,escapeIndex);
|
||||
@ -338,6 +348,7 @@ void btQuantizedBvh::reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallb
|
||||
|
||||
int maxIterations = 0;
|
||||
|
||||
|
||||
void btQuantizedBvh::walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
|
||||
{
|
||||
btAssert(!m_useQuantization);
|
||||
@ -352,7 +363,7 @@ void btQuantizedBvh::walkStacklessTree(btNodeOverlapCallback* nodeCallback,const
|
||||
while (curIndex < m_curNodeIndex)
|
||||
{
|
||||
//catch bugs in tree data
|
||||
assert (walkIterations < m_curNodeIndex);
|
||||
btAssert (walkIterations < m_curNodeIndex);
|
||||
|
||||
walkIterations++;
|
||||
aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
|
||||
@ -434,6 +445,96 @@ void btQuantizedBvh::walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantize
|
||||
|
||||
|
||||
|
||||
void btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const
|
||||
{
|
||||
btAssert(!m_useQuantization);
|
||||
|
||||
const btOptimizedBvhNode* rootNode = &m_contiguousNodes[0];
|
||||
int escapeIndex, curIndex = 0;
|
||||
int walkIterations = 0;
|
||||
bool isLeafNode;
|
||||
//PCK: unsigned instead of bool
|
||||
unsigned aabbOverlap=0;
|
||||
unsigned rayBoxOverlap=0;
|
||||
btScalar lambda_max = 1.0;
|
||||
|
||||
/* Quick pruning by quantized box */
|
||||
btVector3 rayAabbMin = raySource;
|
||||
btVector3 rayAabbMax = raySource;
|
||||
rayAabbMin.setMin(rayTarget);
|
||||
rayAabbMax.setMax(rayTarget);
|
||||
|
||||
/* Add box cast extents to bounding box */
|
||||
rayAabbMin += aabbMin;
|
||||
rayAabbMax += aabbMax;
|
||||
|
||||
#ifdef RAYAABB2
|
||||
btVector3 rayDir = (rayTarget-raySource);
|
||||
rayDir.normalize ();
|
||||
lambda_max = rayDir.dot(rayTarget-raySource);
|
||||
///what about division by zero? --> just set rayDirection[i] to 1.0
|
||||
btVector3 rayDirectionInverse;
|
||||
rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
|
||||
rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
|
||||
rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
|
||||
unsigned int sign[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0};
|
||||
#endif
|
||||
|
||||
btVector3 bounds[2];
|
||||
|
||||
while (curIndex < m_curNodeIndex)
|
||||
{
|
||||
btScalar param = 1.0;
|
||||
//catch bugs in tree data
|
||||
btAssert (walkIterations < m_curNodeIndex);
|
||||
|
||||
walkIterations++;
|
||||
|
||||
bounds[0] = rootNode->m_aabbMinOrg;
|
||||
bounds[1] = rootNode->m_aabbMaxOrg;
|
||||
/* Add box cast extents */
|
||||
bounds[0] += aabbMin;
|
||||
bounds[1] += aabbMax;
|
||||
|
||||
aabbOverlap = TestAabbAgainstAabb2(rayAabbMin,rayAabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
|
||||
//perhaps profile if it is worth doing the aabbOverlap test first
|
||||
|
||||
#ifdef RAYAABB2
|
||||
///careful with this check: need to check division by zero (above) and fix the unQuantize method
|
||||
///thanks Joerg/hiker for the reproduction case!
|
||||
///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858
|
||||
rayBoxOverlap = aabbOverlap ? btRayAabb2 (raySource, rayDirectionInverse, sign, bounds, param, 0.0f, lambda_max) : false;
|
||||
|
||||
#else
|
||||
btVector3 normal;
|
||||
rayBoxOverlap = btRayAabb(raySource, rayTarget,bounds[0],bounds[1],param, normal);
|
||||
#endif
|
||||
|
||||
isLeafNode = rootNode->m_escapeIndex == -1;
|
||||
|
||||
//PCK: unsigned instead of bool
|
||||
if (isLeafNode && (rayBoxOverlap != 0))
|
||||
{
|
||||
nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex);
|
||||
}
|
||||
|
||||
//PCK: unsigned instead of bool
|
||||
if ((rayBoxOverlap != 0) || isLeafNode)
|
||||
{
|
||||
rootNode++;
|
||||
curIndex++;
|
||||
} else
|
||||
{
|
||||
escapeIndex = rootNode->m_escapeIndex;
|
||||
rootNode += escapeIndex;
|
||||
curIndex += escapeIndex;
|
||||
}
|
||||
}
|
||||
if (maxIterations < walkIterations)
|
||||
maxIterations = walkIterations;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const
|
||||
@ -454,9 +555,8 @@ void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback*
|
||||
unsigned rayBoxOverlap = 0;
|
||||
|
||||
btScalar lambda_max = 1.0;
|
||||
#define RAYAABB2
|
||||
|
||||
#ifdef RAYAABB2
|
||||
btVector3 rayFrom = raySource;
|
||||
btVector3 rayDirection = (rayTarget-raySource);
|
||||
rayDirection.normalize ();
|
||||
lambda_max = rayDirection.dot(rayTarget-raySource);
|
||||
@ -502,7 +602,7 @@ void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback*
|
||||
#endif//VISUALLY_ANALYZE_BVH
|
||||
|
||||
//catch bugs in tree data
|
||||
assert (walkIterations < subTreeSize);
|
||||
btAssert (walkIterations < subTreeSize);
|
||||
|
||||
walkIterations++;
|
||||
//PCK: unsigned instead of bool
|
||||
@ -533,7 +633,9 @@ void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback*
|
||||
///thanks Joerg/hiker for the reproduction case!
|
||||
///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858
|
||||
|
||||
//BT_PROFILE("btRayAabb2");
|
||||
rayBoxOverlap = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0f, lambda_max);
|
||||
|
||||
#else
|
||||
rayBoxOverlap = true;//btRayAabb(raySource, rayTarget, bounds[0], bounds[1], param, normal);
|
||||
#endif
|
||||
@ -597,7 +699,7 @@ void btQuantizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallb
|
||||
#endif//VISUALLY_ANALYZE_BVH
|
||||
|
||||
//catch bugs in tree data
|
||||
assert (walkIterations < subTreeSize);
|
||||
btAssert (walkIterations < subTreeSize);
|
||||
|
||||
walkIterations++;
|
||||
//PCK: unsigned instead of bool
|
||||
@ -652,30 +754,25 @@ void btQuantizedBvh::walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallba
|
||||
|
||||
void btQuantizedBvh::reportRayOverlappingNodex (btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget) const
|
||||
{
|
||||
bool fast_path = m_useQuantization && m_traversalMode == TRAVERSAL_STACKLESS;
|
||||
if (fast_path)
|
||||
{
|
||||
walkStacklessQuantizedTreeAgainstRay(nodeCallback, raySource, rayTarget, btVector3(0, 0, 0), btVector3(0, 0, 0), 0, m_curNodeIndex);
|
||||
} else {
|
||||
/* Otherwise fallback to AABB overlap test */
|
||||
btVector3 aabbMin = raySource;
|
||||
btVector3 aabbMax = raySource;
|
||||
aabbMin.setMin(rayTarget);
|
||||
aabbMax.setMax(rayTarget);
|
||||
reportAabbOverlappingNodex(nodeCallback,aabbMin,aabbMax);
|
||||
}
|
||||
reportBoxCastOverlappingNodex(nodeCallback,raySource,rayTarget,btVector3(0,0,0),btVector3(0,0,0));
|
||||
}
|
||||
|
||||
|
||||
void btQuantizedBvh::reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin,const btVector3& aabbMax) const
|
||||
{
|
||||
bool fast_path = m_useQuantization && m_traversalMode == TRAVERSAL_STACKLESS;
|
||||
if (fast_path)
|
||||
//always use stackless
|
||||
|
||||
if (m_useQuantization)
|
||||
{
|
||||
walkStacklessQuantizedTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex);
|
||||
} else {
|
||||
/* Slow path:
|
||||
Construct the bounding box for the entire box cast and send that down the tree */
|
||||
}
|
||||
else
|
||||
{
|
||||
walkStacklessTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex);
|
||||
}
|
||||
/*
|
||||
{
|
||||
//recursive traversal
|
||||
btVector3 qaabbMin = raySource;
|
||||
btVector3 qaabbMax = raySource;
|
||||
qaabbMin.setMin(rayTarget);
|
||||
@ -684,6 +781,8 @@ void btQuantizedBvh::reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCa
|
||||
qaabbMax += aabbMax;
|
||||
reportAabbOverlappingNodex(nodeCallback,qaabbMin,qaabbMax);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -716,17 +815,19 @@ void btQuantizedBvh::assignInternalNodeFromLeafNode(int internalNode,int leafNod
|
||||
//PCK: include
|
||||
#include <new>
|
||||
|
||||
#if 0
|
||||
//PCK: consts
|
||||
static const unsigned BVH_ALIGNMENT = 16;
|
||||
static const unsigned BVH_ALIGNMENT_MASK = BVH_ALIGNMENT-1;
|
||||
|
||||
static const unsigned BVH_ALIGNMENT_BLOCKS = 2;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
unsigned int btQuantizedBvh::getAlignmentSerializationPadding()
|
||||
{
|
||||
return BVH_ALIGNMENT_BLOCKS * BVH_ALIGNMENT;
|
||||
// I changed this to 0 since the extra padding is not needed or used.
|
||||
return 0;//BVH_ALIGNMENT_BLOCKS * BVH_ALIGNMENT;
|
||||
}
|
||||
|
||||
unsigned btQuantizedBvh::calculateSerializeBufferSize()
|
||||
@ -742,7 +843,7 @@ unsigned btQuantizedBvh::calculateSerializeBufferSize()
|
||||
|
||||
bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian)
|
||||
{
|
||||
assert(m_subtreeHeaderCount == m_SubtreeHeaders.size());
|
||||
btAssert(m_subtreeHeaderCount == m_SubtreeHeaders.size());
|
||||
m_subtreeHeaderCount = m_SubtreeHeaders.size();
|
||||
|
||||
/* if (i_dataBufferSize < calculateSerializeBufferSize() || o_alignedDataBuffer == NULL || (((unsigned)o_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0))
|
||||
@ -829,6 +930,11 @@ bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBuffe
|
||||
}
|
||||
}
|
||||
nodeData += sizeof(btQuantizedBvhNode) * nodeCount;
|
||||
|
||||
// this clears the pointer in the member variable it doesn't really do anything to the data
|
||||
// it does call the destructor on the contained objects, but they are all classes with no destructor defined
|
||||
// so the memory (which is not freed) is left alone
|
||||
targetBvh->m_quantizedContiguousNodes.initializeFromBuffer(NULL, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -859,6 +965,11 @@ bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBuffe
|
||||
}
|
||||
}
|
||||
nodeData += sizeof(btOptimizedBvhNode) * nodeCount;
|
||||
|
||||
// this clears the pointer in the member variable it doesn't really do anything to the data
|
||||
// it does call the destructor on the contained objects, but they are all classes with no destructor defined
|
||||
// so the memory (which is not freed) is left alone
|
||||
targetBvh->m_contiguousNodes.initializeFromBuffer(NULL, 0, 0);
|
||||
}
|
||||
|
||||
sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK;
|
||||
@ -896,12 +1007,23 @@ bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBuffe
|
||||
|
||||
targetBvh->m_SubtreeHeaders[i].m_rootNodeIndex = (m_SubtreeHeaders[i].m_rootNodeIndex);
|
||||
targetBvh->m_SubtreeHeaders[i].m_subtreeSize = (m_SubtreeHeaders[i].m_subtreeSize);
|
||||
targetBvh->m_SubtreeHeaders[i] = m_SubtreeHeaders[i];
|
||||
|
||||
// need to clear padding in destination buffer
|
||||
targetBvh->m_SubtreeHeaders[i].m_padding[0] = 0;
|
||||
targetBvh->m_SubtreeHeaders[i].m_padding[1] = 0;
|
||||
targetBvh->m_SubtreeHeaders[i].m_padding[2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
nodeData += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount;
|
||||
|
||||
// this clears the pointer in the member variable it doesn't really do anything to the data
|
||||
// it does call the destructor on the contained objects, but they are all classes with no destructor defined
|
||||
// so the memory (which is not freed) is left alone
|
||||
targetBvh->m_SubtreeHeaders.initializeFromBuffer(NULL, 0, 0);
|
||||
|
||||
// this wipes the virtual function table pointer at the start of the buffer for the class
|
||||
*((void**)o_alignedDataBuffer) = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1015,11 +1137,12 @@ btQuantizedBvh *btQuantizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, un
|
||||
btQuantizedBvh::btQuantizedBvh(btQuantizedBvh &self, bool /* ownsMemory */) :
|
||||
m_bvhAabbMin(self.m_bvhAabbMin),
|
||||
m_bvhAabbMax(self.m_bvhAabbMax),
|
||||
m_bvhQuantization(self.m_bvhQuantization)
|
||||
m_bvhQuantization(self.m_bvhQuantization),
|
||||
m_bulletVersion(BT_BULLET_VERSION)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -158,41 +158,43 @@ typedef btAlignedObjectArray<btBvhSubtreeInfo> BvhSubtreeInfoArray;
|
||||
///It is recommended to use quantization for better performance and lower memory requirements.
|
||||
ATTRIBUTE_ALIGNED16(class) btQuantizedBvh
|
||||
{
|
||||
protected:
|
||||
|
||||
NodeArray m_leafNodes;
|
||||
NodeArray m_contiguousNodes;
|
||||
|
||||
QuantizedNodeArray m_quantizedLeafNodes;
|
||||
|
||||
QuantizedNodeArray m_quantizedContiguousNodes;
|
||||
|
||||
int m_curNodeIndex;
|
||||
|
||||
|
||||
//quantization data
|
||||
bool m_useQuantization;
|
||||
btVector3 m_bvhAabbMin;
|
||||
btVector3 m_bvhAabbMax;
|
||||
btVector3 m_bvhQuantization;
|
||||
public:
|
||||
BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
enum btTraversalMode
|
||||
{
|
||||
TRAVERSAL_STACKLESS = 0,
|
||||
TRAVERSAL_STACKLESS_CACHE_FRIENDLY,
|
||||
TRAVERSAL_RECURSIVE
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
btTraversalMode m_traversalMode;
|
||||
|
||||
btVector3 m_bvhAabbMin;
|
||||
btVector3 m_bvhAabbMax;
|
||||
btVector3 m_bvhQuantization;
|
||||
|
||||
int m_bulletVersion; //for serialization versioning. It could also be used to detect endianess.
|
||||
|
||||
int m_curNodeIndex;
|
||||
//quantization data
|
||||
bool m_useQuantization;
|
||||
|
||||
|
||||
|
||||
NodeArray m_leafNodes;
|
||||
NodeArray m_contiguousNodes;
|
||||
QuantizedNodeArray m_quantizedLeafNodes;
|
||||
QuantizedNodeArray m_quantizedContiguousNodes;
|
||||
|
||||
btTraversalMode m_traversalMode;
|
||||
BvhSubtreeInfoArray m_SubtreeHeaders;
|
||||
|
||||
//This is only used for serialization so we don't have to add serialization directly to btAlignedObjectArray
|
||||
int m_subtreeHeaderCount;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///two versions, one for quantized and normal nodes. This allows code-reuse while maintaining readability (no template/macro!)
|
||||
///this might be refactored into a virtual, it is usually not calculated at run-time
|
||||
@ -296,6 +298,7 @@ protected:
|
||||
|
||||
void walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const;
|
||||
void walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const;
|
||||
void walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const;
|
||||
|
||||
///tree traversal designed for small-memory processors like PS3 SPU
|
||||
void walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const;
|
||||
@ -307,30 +310,14 @@ protected:
|
||||
void walkRecursiveQuantizedTreeAgainstQuantizedTree(const btQuantizedBvhNode* treeNodeA,const btQuantizedBvhNode* treeNodeB,btNodeOverlapCallback* nodeCallback) const;
|
||||
|
||||
|
||||
#define USE_BANCHLESS 1
|
||||
#ifdef USE_BANCHLESS
|
||||
//This block replaces the block below and uses no branches, and replaces the 8 bit return with a 32 bit return for improved performance (~3x on XBox 360)
|
||||
SIMD_FORCE_INLINE unsigned testQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) const
|
||||
{
|
||||
return static_cast<unsigned int>(btSelect((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0])
|
||||
& (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2])
|
||||
& (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])),
|
||||
1, 0));
|
||||
}
|
||||
#else
|
||||
SIMD_FORCE_INLINE bool testQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) const
|
||||
{
|
||||
bool overlap = true;
|
||||
overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
|
||||
overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
|
||||
overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
|
||||
return overlap;
|
||||
}
|
||||
#endif //USE_BANCHLESS
|
||||
|
||||
|
||||
void updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex);
|
||||
|
||||
public:
|
||||
|
||||
BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
btQuantizedBvh();
|
||||
|
||||
virtual ~btQuantizedBvh();
|
||||
@ -363,7 +350,7 @@ public:
|
||||
btVector3 v = (point - m_bvhAabbMin) * m_bvhQuantization;
|
||||
///Make sure rounding is done in a way that unQuantize(quantizeWithClamp(...)) is conservative
|
||||
///end-points always set the first bit, so that they are sorted properly (so that neighbouring AABBs overlap properly)
|
||||
///todo: double-check this
|
||||
///@todo: double-check this
|
||||
if (isMax)
|
||||
{
|
||||
out[0] = (unsigned short) (((unsigned short)(v.getX()+btScalar(1.)) | 1));
|
||||
|
@ -55,6 +55,7 @@ btSimpleBroadphase::btSimpleBroadphase(int maxProxies, btOverlappingPairCache* o
|
||||
m_maxHandles = maxProxies;
|
||||
m_numHandles = 0;
|
||||
m_firstFreeHandle = 0;
|
||||
m_LastHandleIndex = -1;
|
||||
|
||||
|
||||
{
|
||||
@ -88,7 +89,7 @@ btBroadphaseProxy* btSimpleBroadphase::createProxy( const btVector3& aabbMin,
|
||||
btAssert(0);
|
||||
return 0; //should never happen, but don't let the game crash ;-)
|
||||
}
|
||||
assert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]);
|
||||
btAssert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]);
|
||||
|
||||
int newHandleIndex = allocHandle();
|
||||
btSimpleBroadphaseProxy* proxy = new (&m_pHandles[newHandleIndex])btSimpleBroadphaseProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy);
|
||||
@ -137,14 +138,32 @@ void btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg,btDispatcher*
|
||||
|
||||
}
|
||||
|
||||
void btSimpleBroadphase::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const
|
||||
{
|
||||
const btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy);
|
||||
aabbMin = sbp->m_aabbMin;
|
||||
aabbMax = sbp->m_aabbMax;
|
||||
}
|
||||
|
||||
void btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* /*dispatcher*/)
|
||||
{
|
||||
btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy);
|
||||
sbp->m_min = aabbMin;
|
||||
sbp->m_max = aabbMax;
|
||||
sbp->m_aabbMin = aabbMin;
|
||||
sbp->m_aabbMax = aabbMax;
|
||||
}
|
||||
|
||||
|
||||
void btSimpleBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin,const btVector3& aabbMax)
|
||||
{
|
||||
for (int i=0; i <= m_LastHandleIndex; i++)
|
||||
{
|
||||
btSimpleBroadphaseProxy* proxy = &m_pHandles[i];
|
||||
if(!proxy->m_clientObject)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
rayCallback.process(proxy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -154,9 +173,9 @@ void btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbM
|
||||
|
||||
bool btSimpleBroadphase::aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1)
|
||||
{
|
||||
return proxy0->m_min[0] <= proxy1->m_max[0] && proxy1->m_min[0] <= proxy0->m_max[0] &&
|
||||
proxy0->m_min[1] <= proxy1->m_max[1] && proxy1->m_min[1] <= proxy0->m_max[1] &&
|
||||
proxy0->m_min[2] <= proxy1->m_max[2] && proxy1->m_min[2] <= proxy0->m_max[2];
|
||||
return proxy0->m_aabbMin[0] <= proxy1->m_aabbMax[0] && proxy1->m_aabbMin[0] <= proxy0->m_aabbMax[0] &&
|
||||
proxy0->m_aabbMin[1] <= proxy1->m_aabbMax[1] && proxy1->m_aabbMin[1] <= proxy0->m_aabbMax[1] &&
|
||||
proxy0->m_aabbMin[2] <= proxy1->m_aabbMax[2] && proxy1->m_aabbMin[2] <= proxy0->m_aabbMax[2];
|
||||
|
||||
}
|
||||
|
||||
@ -176,18 +195,25 @@ void btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
|
||||
{
|
||||
//first check for new overlapping pairs
|
||||
int i,j;
|
||||
|
||||
if (m_numHandles >= 0)
|
||||
{
|
||||
|
||||
for (i=0;i<m_numHandles;i++)
|
||||
int new_largest_index = -1;
|
||||
for (i=0; i <= m_LastHandleIndex; i++)
|
||||
{
|
||||
btSimpleBroadphaseProxy* proxy0 = &m_pHandles[i];
|
||||
|
||||
for (j=i+1;j<m_numHandles;j++)
|
||||
if(!proxy0->m_clientObject)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
new_largest_index = i;
|
||||
for (j=i+1; j <= m_LastHandleIndex; j++)
|
||||
{
|
||||
btSimpleBroadphaseProxy* proxy1 = &m_pHandles[j];
|
||||
btAssert(proxy0 != proxy1);
|
||||
if(!proxy1->m_clientObject)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0);
|
||||
btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1);
|
||||
@ -211,6 +237,8 @@ void btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
|
||||
}
|
||||
}
|
||||
|
||||
m_LastHandleIndex = new_largest_index;
|
||||
|
||||
if (m_ownsPairCache && m_pairCache->hasDeferredRemoval())
|
||||
{
|
||||
|
||||
@ -296,5 +324,7 @@ bool btSimpleBroadphase::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseP
|
||||
return aabbOverlap(p0,p1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void btSimpleBroadphase::resetPool(btDispatcher* dispatcher)
|
||||
{
|
||||
//not yet
|
||||
}
|
||||
|
@ -22,8 +22,6 @@ subject to the following restrictions:
|
||||
|
||||
struct btSimpleBroadphaseProxy : public btBroadphaseProxy
|
||||
{
|
||||
btVector3 m_min;
|
||||
btVector3 m_max;
|
||||
int m_nextFree;
|
||||
|
||||
// int m_handleId;
|
||||
@ -31,9 +29,8 @@ struct btSimpleBroadphaseProxy : public btBroadphaseProxy
|
||||
|
||||
btSimpleBroadphaseProxy() {};
|
||||
|
||||
btSimpleBroadphaseProxy(const btPoint3& minpt,const btPoint3& maxpt,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,void* multiSapProxy)
|
||||
:btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy),
|
||||
m_min(minpt),m_max(maxpt)
|
||||
btSimpleBroadphaseProxy(const btVector3& minpt,const btVector3& maxpt,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,void* multiSapProxy)
|
||||
:btBroadphaseProxy(minpt,maxpt,userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy)
|
||||
{
|
||||
(void)shapeType;
|
||||
}
|
||||
@ -56,6 +53,7 @@ protected:
|
||||
|
||||
int m_numHandles; // number of active handles
|
||||
int m_maxHandles; // max number of handles
|
||||
int m_LastHandleIndex;
|
||||
|
||||
btSimpleBroadphaseProxy* m_pHandles; // handles pool
|
||||
|
||||
@ -68,6 +66,10 @@ protected:
|
||||
int freeHandle = m_firstFreeHandle;
|
||||
m_firstFreeHandle = m_pHandles[freeHandle].GetNextFree();
|
||||
m_numHandles++;
|
||||
if(freeHandle > m_LastHandleIndex)
|
||||
{
|
||||
m_LastHandleIndex = freeHandle;
|
||||
}
|
||||
return freeHandle;
|
||||
}
|
||||
|
||||
@ -75,10 +77,15 @@ protected:
|
||||
{
|
||||
int handle = int(proxy-m_pHandles);
|
||||
btAssert(handle >= 0 && handle < m_maxHandles);
|
||||
|
||||
if(handle == m_LastHandleIndex)
|
||||
{
|
||||
m_LastHandleIndex--;
|
||||
}
|
||||
proxy->SetNextFree(m_firstFreeHandle);
|
||||
m_firstFreeHandle = handle;
|
||||
|
||||
proxy->m_clientObject = 0;
|
||||
|
||||
m_numHandles--;
|
||||
}
|
||||
|
||||
@ -95,6 +102,15 @@ protected:
|
||||
return proxy0;
|
||||
}
|
||||
|
||||
inline const btSimpleBroadphaseProxy* getSimpleProxyFromProxy(btBroadphaseProxy* proxy) const
|
||||
{
|
||||
const btSimpleBroadphaseProxy* proxy0 = static_cast<const btSimpleBroadphaseProxy*>(proxy);
|
||||
return proxy0;
|
||||
}
|
||||
|
||||
///reset broadphase internal structures, to ensure determinism/reproducability
|
||||
virtual void resetPool(btDispatcher* dispatcher);
|
||||
|
||||
|
||||
void validate();
|
||||
|
||||
@ -117,6 +133,9 @@ public:
|
||||
|
||||
virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
|
||||
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher);
|
||||
virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
|
||||
|
||||
virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0),const btVector3& aabbMax=btVector3(0,0,0));
|
||||
|
||||
btOverlappingPairCache* getOverlappingPairCache()
|
||||
{
|
||||
|
383
extern/bullet2/src/BulletCollision/CMakeLists.txt
vendored
383
extern/bullet2/src/BulletCollision/CMakeLists.txt
vendored
@ -1,153 +1,234 @@
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/src }
|
||||
INCLUDE_DIRECTORIES( ${BULLET_PHYSICS_SOURCE_DIR}/src } )
|
||||
|
||||
SET(BulletCollision_SRCS
|
||||
BroadphaseCollision/btAxisSweep3.cpp
|
||||
BroadphaseCollision/btBroadphaseProxy.cpp
|
||||
BroadphaseCollision/btCollisionAlgorithm.cpp
|
||||
BroadphaseCollision/btDispatcher.cpp
|
||||
BroadphaseCollision/btDbvtBroadphase.cpp
|
||||
BroadphaseCollision/btDbvt.cpp
|
||||
BroadphaseCollision/btMultiSapBroadphase.cpp
|
||||
BroadphaseCollision/btOverlappingPairCache.cpp
|
||||
BroadphaseCollision/btQuantizedBvh.cpp
|
||||
BroadphaseCollision/btSimpleBroadphase.cpp
|
||||
CollisionDispatch/btActivatingCollisionAlgorithm.cpp
|
||||
CollisionDispatch/btCollisionDispatcher.cpp
|
||||
CollisionDispatch/btCollisionObject.cpp
|
||||
CollisionDispatch/btCollisionWorld.cpp
|
||||
CollisionDispatch/btCompoundCollisionAlgorithm.cpp
|
||||
CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
|
||||
CollisionDispatch/btDefaultCollisionConfiguration.cpp
|
||||
CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
|
||||
CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
|
||||
CollisionDispatch/btBoxBoxDetector.cpp
|
||||
CollisionDispatch/btGhostObject.cpp
|
||||
CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
|
||||
CollisionDispatch/btConvexPlaneCollisionAlgorithm.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/btConvexPointCloudShape.cpp
|
||||
CollisionShapes/btConvexShape.cpp
|
||||
CollisionShapes/btConvexInternalShape.cpp
|
||||
CollisionShapes/btConvexTriangleMeshShape.cpp
|
||||
CollisionShapes/btCylinderShape.cpp
|
||||
CollisionShapes/btEmptyShape.cpp
|
||||
CollisionShapes/btHeightfieldTerrainShape.cpp
|
||||
CollisionShapes/btMinkowskiSumShape.cpp
|
||||
CollisionShapes/btMultimaterialTriangleMeshShape.cpp
|
||||
CollisionShapes/btMultiSphereShape.cpp
|
||||
CollisionShapes/btOptimizedBvh.cpp
|
||||
CollisionShapes/btPolyhedralConvexShape.cpp
|
||||
CollisionShapes/btScaledBvhTriangleMeshShape.cpp
|
||||
CollisionShapes/btTetrahedronShape.cpp
|
||||
CollisionShapes/btSphereShape.cpp
|
||||
CollisionShapes/btShapeHull.cpp
|
||||
CollisionShapes/btStaticPlaneShape.cpp
|
||||
CollisionShapes/btStridingMeshInterface.cpp
|
||||
CollisionShapes/btTriangleCallback.cpp
|
||||
CollisionShapes/btTriangleBuffer.cpp
|
||||
CollisionShapes/btTriangleIndexVertexArray.cpp
|
||||
CollisionShapes/btTriangleIndexVertexMaterialArray.cpp
|
||||
CollisionShapes/btTriangleMesh.cpp
|
||||
CollisionShapes/btTriangleMeshShape.cpp
|
||||
CollisionShapes/btUniformScalingShape.cpp
|
||||
Gimpact/btContactProcessing.cpp
|
||||
Gimpact/btGImpactShape.cpp
|
||||
Gimpact/gim_contact.cpp
|
||||
Gimpact/btGImpactBvh.cpp
|
||||
Gimpact/btGenericPoolAllocator.cpp
|
||||
Gimpact/gim_memory.cpp
|
||||
Gimpact/btGImpactCollisionAlgorithm.cpp
|
||||
Gimpact/btTriangleShapeEx.cpp
|
||||
Gimpact/gim_tri_collision.cpp
|
||||
Gimpact/btGImpactQuantizedBvh.cpp
|
||||
Gimpact/gim_box_set.cpp
|
||||
NarrowPhaseCollision/btContinuousConvexCollision.cpp
|
||||
NarrowPhaseCollision/btGjkEpa2.cpp
|
||||
NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
|
||||
NarrowPhaseCollision/btConvexCast.cpp
|
||||
NarrowPhaseCollision/btGjkConvexCast.cpp
|
||||
NarrowPhaseCollision/btGjkPairDetector.cpp
|
||||
NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
|
||||
NarrowPhaseCollision/btPersistentManifold.cpp
|
||||
NarrowPhaseCollision/btRaycastCallback.cpp
|
||||
NarrowPhaseCollision/btSubSimplexConvexCast.cpp
|
||||
NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
|
||||
)
|
||||
|
||||
ADD_LIBRARY(LibBulletCollision
|
||||
BroadphaseCollision/btAxisSweep3.cpp
|
||||
BroadphaseCollision/btAxisSweep3.h
|
||||
BroadphaseCollision/btBroadphaseProxy.cpp
|
||||
BroadphaseCollision/btBroadphaseProxy.h
|
||||
BroadphaseCollision/btCollisionAlgorithm.cpp
|
||||
BroadphaseCollision/btCollisionAlgorithm.h
|
||||
BroadphaseCollision/btDispatcher.cpp
|
||||
BroadphaseCollision/btDispatcher.h
|
||||
BroadphaseCollision/btDbvtBroadphase.cpp
|
||||
BroadphaseCollision/btDbvtBroadphase.h
|
||||
BroadphaseCollision/btDbvt.cpp
|
||||
BroadphaseCollision/btDbvt.h
|
||||
BroadphaseCollision/btMultiSapBroadphase.cpp
|
||||
BroadphaseCollision/btMultiSapBroadphase.h
|
||||
BroadphaseCollision/btOverlappingPairCache.cpp
|
||||
BroadphaseCollision/btOverlappingPairCache.h
|
||||
BroadphaseCollision/btOverlappingPairCallback.h
|
||||
BroadphaseCollision/btQuantizedBvh.cpp
|
||||
BroadphaseCollision/btQuantizedBvh.h
|
||||
BroadphaseCollision/btSimpleBroadphase.cpp
|
||||
BroadphaseCollision/btSimpleBroadphase.h
|
||||
CollisionDispatch/btCollisionDispatcher.cpp
|
||||
CollisionDispatch/btCollisionDispatcher.h
|
||||
CollisionDispatch/btCollisionObject.cpp
|
||||
CollisionDispatch/btCollisionObject.h
|
||||
CollisionDispatch/btCollisionWorld.cpp
|
||||
CollisionDispatch/btCollisionWorld.h
|
||||
CollisionDispatch/btCompoundCollisionAlgorithm.cpp
|
||||
CollisionDispatch/btCompoundCollisionAlgorithm.h
|
||||
CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
|
||||
CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
|
||||
CollisionDispatch/btDefaultCollisionConfiguration.cpp
|
||||
CollisionDispatch/btDefaultCollisionConfiguration.h
|
||||
CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
|
||||
CollisionDispatch/btSphereSphereCollisionAlgorithm.h
|
||||
CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
|
||||
CollisionDispatch/btBoxBoxCollisionAlgorithm.h
|
||||
CollisionDispatch/btBoxBoxDetector.cpp
|
||||
CollisionDispatch/btBoxBoxDetector.h
|
||||
CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
|
||||
CollisionDispatch/btSphereBoxCollisionAlgorithm.h
|
||||
CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
|
||||
CollisionDispatch/btConvexPlaneCollisionAlgorithm.h
|
||||
CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
|
||||
CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
|
||||
CollisionDispatch/btConvexConvexAlgorithm.cpp
|
||||
CollisionDispatch/btConvexConvexAlgorithm.h
|
||||
CollisionDispatch/btEmptyCollisionAlgorithm.cpp
|
||||
CollisionDispatch/btEmptyCollisionAlgorithm.h
|
||||
CollisionDispatch/btManifoldResult.cpp
|
||||
CollisionDispatch/btManifoldResult.h
|
||||
CollisionDispatch/btSimulationIslandManager.cpp
|
||||
CollisionDispatch/btSimulationIslandManager.h
|
||||
CollisionDispatch/btUnionFind.cpp
|
||||
CollisionDispatch/btUnionFind.h
|
||||
CollisionDispatch/SphereTriangleDetector.cpp
|
||||
CollisionDispatch/SphereTriangleDetector.h
|
||||
CollisionShapes/btBoxShape.cpp
|
||||
CollisionShapes/btBoxShape.h
|
||||
CollisionShapes/btBvhTriangleMeshShape.cpp
|
||||
CollisionShapes/btBvhTriangleMeshShape.h
|
||||
CollisionShapes/btCapsuleShape.cpp
|
||||
CollisionShapes/btCapsuleShape.h
|
||||
CollisionShapes/btCollisionShape.cpp
|
||||
CollisionShapes/btCollisionShape.h
|
||||
CollisionShapes/btCompoundShape.cpp
|
||||
CollisionShapes/btCompoundShape.h
|
||||
CollisionShapes/btConcaveShape.cpp
|
||||
CollisionShapes/btConcaveShape.h
|
||||
CollisionShapes/btConeShape.cpp
|
||||
CollisionShapes/btConeShape.h
|
||||
CollisionShapes/btConvexHullShape.cpp
|
||||
CollisionShapes/btConvexHullShape.h
|
||||
CollisionShapes/btConvexShape.cpp
|
||||
CollisionShapes/btConvexShape.h
|
||||
CollisionShapes/btConvexInternalShape.cpp
|
||||
CollisionShapes/btConvexInternalShape.h
|
||||
CollisionShapes/btConvexTriangleMeshShape.cpp
|
||||
CollisionShapes/btConvexTriangleMeshShape.h
|
||||
CollisionShapes/btCylinderShape.cpp
|
||||
CollisionShapes/btCylinderShape.h
|
||||
CollisionShapes/btEmptyShape.cpp
|
||||
CollisionShapes/btEmptyShape.h
|
||||
CollisionShapes/btHeightfieldTerrainShape.cpp
|
||||
CollisionShapes/btHeightfieldTerrainShape.h
|
||||
CollisionShapes/btMinkowskiSumShape.cpp
|
||||
CollisionShapes/btMinkowskiSumShape.h
|
||||
CollisionShapes/btMaterial.h
|
||||
CollisionShapes/btMultimaterialTriangleMeshShape.cpp
|
||||
CollisionShapes/btMultimaterialTriangleMeshShape.h
|
||||
CollisionShapes/btMultiSphereShape.cpp
|
||||
CollisionShapes/btMultiSphereShape.h
|
||||
CollisionShapes/btOptimizedBvh.cpp
|
||||
CollisionShapes/btOptimizedBvh.h
|
||||
CollisionShapes/btPolyhedralConvexShape.cpp
|
||||
CollisionShapes/btPolyhedralConvexShape.h
|
||||
CollisionShapes/btScaledBvhTriangleMeshShape.cpp
|
||||
CollisionShapes/btScaledBvhTriangleMeshShape.h
|
||||
CollisionShapes/btTetrahedronShape.cpp
|
||||
CollisionShapes/btTetrahedronShape.h
|
||||
CollisionShapes/btSphereShape.cpp
|
||||
CollisionShapes/btSphereShape.h
|
||||
CollisionShapes/btShapeHull.h
|
||||
CollisionShapes/btShapeHull.cpp
|
||||
CollisionShapes/btStaticPlaneShape.cpp
|
||||
CollisionShapes/btStaticPlaneShape.h
|
||||
CollisionShapes/btStridingMeshInterface.cpp
|
||||
CollisionShapes/btStridingMeshInterface.h
|
||||
CollisionShapes/btTriangleCallback.cpp
|
||||
CollisionShapes/btTriangleCallback.h
|
||||
CollisionShapes/btTriangleBuffer.cpp
|
||||
CollisionShapes/btTriangleBuffer.h
|
||||
CollisionShapes/btTriangleIndexVertexArray.cpp
|
||||
CollisionShapes/btTriangleIndexVertexArray.h
|
||||
CollisionShapes/btTriangleIndexVertexMaterialArray.h
|
||||
CollisionShapes/btTriangleIndexVertexMaterialArray.cpp
|
||||
CollisionShapes/btTriangleMesh.cpp
|
||||
CollisionShapes/btTriangleMesh.h
|
||||
CollisionShapes/btTriangleMeshShape.cpp
|
||||
CollisionShapes/btTriangleMeshShape.h
|
||||
CollisionShapes/btUniformScalingShape.cpp
|
||||
CollisionShapes/btUniformScalingShape.h
|
||||
NarrowPhaseCollision/btContinuousConvexCollision.cpp
|
||||
NarrowPhaseCollision/btContinuousConvexCollision.h
|
||||
NarrowPhaseCollision/btGjkEpa.cpp
|
||||
NarrowPhaseCollision/btGjkEpa.h
|
||||
NarrowPhaseCollision/btGjkEpa2.cpp
|
||||
NarrowPhaseCollision/btGjkEpa2.h
|
||||
NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
|
||||
NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h
|
||||
NarrowPhaseCollision/btConvexCast.cpp
|
||||
NarrowPhaseCollision/btConvexCast.h
|
||||
NarrowPhaseCollision/btGjkConvexCast.cpp
|
||||
NarrowPhaseCollision/btGjkConvexCast.h
|
||||
NarrowPhaseCollision/btGjkPairDetector.cpp
|
||||
NarrowPhaseCollision/btGjkPairDetector.h
|
||||
NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
|
||||
NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
|
||||
NarrowPhaseCollision/btPersistentManifold.cpp
|
||||
NarrowPhaseCollision/btPersistentManifold.h
|
||||
NarrowPhaseCollision/btRaycastCallback.cpp
|
||||
NarrowPhaseCollision/btRaycastCallback.h
|
||||
NarrowPhaseCollision/btSubSimplexConvexCast.cpp
|
||||
NarrowPhaseCollision/btSubSimplexConvexCast.h
|
||||
NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
|
||||
NarrowPhaseCollision/btVoronoiSimplexSolver.h
|
||||
|
||||
SET(Root_HDRS
|
||||
../btBulletCollisionCommon.h
|
||||
)
|
||||
SET(BroadphaseCollision_HDRS
|
||||
BroadphaseCollision/btAxisSweep3.h
|
||||
BroadphaseCollision/btBroadphaseInterface.h
|
||||
BroadphaseCollision/btBroadphaseProxy.h
|
||||
BroadphaseCollision/btCollisionAlgorithm.h
|
||||
BroadphaseCollision/btDispatcher.h
|
||||
BroadphaseCollision/btDbvtBroadphase.h
|
||||
BroadphaseCollision/btDbvt.h
|
||||
BroadphaseCollision/btMultiSapBroadphase.h
|
||||
BroadphaseCollision/btOverlappingPairCache.h
|
||||
BroadphaseCollision/btOverlappingPairCallback.h
|
||||
BroadphaseCollision/btQuantizedBvh.h
|
||||
BroadphaseCollision/btSimpleBroadphase.h
|
||||
)
|
||||
SET(CollisionDispatch_HDRS
|
||||
CollisionDispatch/btActivatingCollisionAlgorithm.h
|
||||
CollisionDispatch/btCollisionConfiguration.h
|
||||
CollisionDispatch/btCollisionCreateFunc.h
|
||||
CollisionDispatch/btCollisionDispatcher.h
|
||||
CollisionDispatch/btCollisionObject.h
|
||||
CollisionDispatch/btCollisionWorld.h
|
||||
CollisionDispatch/btCompoundCollisionAlgorithm.h
|
||||
CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
|
||||
CollisionDispatch/btDefaultCollisionConfiguration.h
|
||||
CollisionDispatch/btSphereSphereCollisionAlgorithm.h
|
||||
CollisionDispatch/btBoxBoxCollisionAlgorithm.h
|
||||
CollisionDispatch/btBoxBoxDetector.h
|
||||
CollisionDispatch/btGhostObject.h
|
||||
CollisionDispatch/btSphereBoxCollisionAlgorithm.h
|
||||
CollisionDispatch/btConvexPlaneCollisionAlgorithm.h
|
||||
CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
|
||||
CollisionDispatch/btConvexConvexAlgorithm.h
|
||||
CollisionDispatch/btEmptyCollisionAlgorithm.h
|
||||
CollisionDispatch/btManifoldResult.h
|
||||
CollisionDispatch/btSimulationIslandManager.h
|
||||
CollisionDispatch/btUnionFind.h
|
||||
CollisionDispatch/SphereTriangleDetector.h
|
||||
)
|
||||
SET(CollisionShapes_HDRS
|
||||
CollisionShapes/btBoxShape.h
|
||||
CollisionShapes/btBvhTriangleMeshShape.h
|
||||
CollisionShapes/btCapsuleShape.h
|
||||
CollisionShapes/btCollisionMargin
|
||||
CollisionShapes/btCollisionShape.h
|
||||
CollisionShapes/btCompoundShape.h
|
||||
CollisionShapes/btConcaveShape.h
|
||||
CollisionShapes/btConeShape.h
|
||||
CollisionShapes/btConvexHullShape.h
|
||||
CollisionShapes/btConvexPointCloudShape.h
|
||||
CollisionShapes/btConvexShape.h
|
||||
CollisionShapes/btConvexInternalShape.h
|
||||
CollisionShapes/btConvexTriangleMeshShape.h
|
||||
CollisionShapes/btCylinderShape.h
|
||||
CollisionShapes/btEmptyShape.h
|
||||
CollisionShapes/btHeightfieldTerrainShape.h
|
||||
CollisionShapes/btMinkowskiSumShape.h
|
||||
CollisionShapes/btMaterial.h
|
||||
CollisionShapes/btMultimaterialTriangleMeshShape.h
|
||||
CollisionShapes/btMultiSphereShape.h
|
||||
CollisionShapes/btOptimizedBvh.h
|
||||
CollisionShapes/btPolyhedralConvexShape.h
|
||||
CollisionShapes/btScaledBvhTriangleMeshShape.h
|
||||
CollisionShapes/btTetrahedronShape.h
|
||||
CollisionShapes/btSphereShape.h
|
||||
CollisionShapes/btShapeHull.h
|
||||
CollisionShapes/btStaticPlaneShape.h
|
||||
CollisionShapes/btStridingMeshInterface.h
|
||||
CollisionShapes/btTriangleCallback.h
|
||||
CollisionShapes/btTriangleBuffer.h
|
||||
CollisionShapes/btTriangleIndexVertexArray.h
|
||||
CollisionShapes/btTriangleIndexVertexMaterialArray.h
|
||||
CollisionShapes/btTriangleMesh.h
|
||||
CollisionShapes/btTriangleMeshShape.h
|
||||
CollisionShapes/btUniformScalingShape.h
|
||||
)
|
||||
SET(Gimpact_HDRS
|
||||
Gimpact/btGImpactShape.h
|
||||
Gimpact/gim_contact.h
|
||||
Gimpact/btGImpactBvh.h
|
||||
Gimpact/btGenericPoolAllocator.h
|
||||
Gimpact/gim_memory.h
|
||||
Gimpact/btGImpactCollisionAlgorithm.h
|
||||
Gimpact/btTriangleShapeEx.h
|
||||
Gimpact/gim_tri_collision.h
|
||||
Gimpact/btGImpactQuantizedBvh.h
|
||||
Gimpact/gim_box_set.h
|
||||
)
|
||||
SET(NarrowPhaseCollision_HDRS
|
||||
NarrowPhaseCollision/btContinuousConvexCollision.h
|
||||
NarrowPhaseCollision/btConvexCast.h
|
||||
NarrowPhaseCollision/btConvexPenetrationDepthSolver.h
|
||||
NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h
|
||||
NarrowPhaseCollision/btGjkConvexCast.h
|
||||
NarrowPhaseCollision/btGjkEpa2.h
|
||||
NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h
|
||||
NarrowPhaseCollision/btGjkPairDetector.h
|
||||
NarrowPhaseCollision/btManifoldPoint.h
|
||||
NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
|
||||
NarrowPhaseCollision/btPersistentManifold.h
|
||||
NarrowPhaseCollision/btPointCollector.h
|
||||
NarrowPhaseCollision/btRaycastCallback.h
|
||||
NarrowPhaseCollision/btSimplexSolverInterface.h
|
||||
NarrowPhaseCollision/btSubSimplexConvexCast.h
|
||||
NarrowPhaseCollision/btVoronoiSimplexSolver.h
|
||||
)
|
||||
|
||||
SET(BulletCollision_HDRS
|
||||
${Root_HDRS}
|
||||
${BroadphaseCollision_HDRS}
|
||||
${CollisionDispatch_HDRS}
|
||||
${CollisionShapes_HDRS}
|
||||
${Gimpact_HDRS}
|
||||
${NarrowPhaseCollision_HDRS}
|
||||
)
|
||||
|
||||
|
||||
ADD_LIBRARY(BulletCollision ${BulletCollision_SRCS} ${BulletCollision_HDRS})
|
||||
SET_TARGET_PROPERTIES(BulletCollision PROPERTIES VERSION ${BULLET_VERSION})
|
||||
SET_TARGET_PROPERTIES(BulletCollision PROPERTIES SOVERSION ${BULLET_VERSION})
|
||||
IF (BUILD_SHARED_LIBS)
|
||||
TARGET_LINK_LIBRARIES(BulletCollision LinearMath)
|
||||
ENDIF (BUILD_SHARED_LIBS)
|
||||
|
||||
#INSTALL of other files requires CMake 2.6
|
||||
IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
INSTALL(TARGETS BulletCollision DESTINATION lib)
|
||||
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION include FILES_MATCHING PATTERN "*.h")
|
||||
ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
SET_TARGET_PROPERTIES(BulletCollision PROPERTIES FRAMEWORK true)
|
||||
|
||||
SET_TARGET_PROPERTIES(BulletCollision PROPERTIES PUBLIC_HEADER "${Root_HDRS}")
|
||||
# Have to list out sub-directories manually:
|
||||
SET_PROPERTY(SOURCE ${BroadphaseCollision_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/BroadphaseCollision)
|
||||
SET_PROPERTY(SOURCE ${CollisionDispatch_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/CollisionDispatch)
|
||||
SET_PROPERTY(SOURCE ${CollisionShapes_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/CollisionShapes)
|
||||
SET_PROPERTY(SOURCE ${Gimpact_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/Gimpact)
|
||||
SET_PROPERTY(SOURCE ${NarrowPhaseCollision_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/NarrowPhaseCollision)
|
||||
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
|
@ -19,9 +19,10 @@ subject to the following restrictions:
|
||||
#include "BulletCollision/CollisionShapes/btSphereShape.h"
|
||||
|
||||
|
||||
SphereTriangleDetector::SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle)
|
||||
SphereTriangleDetector::SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle,btScalar contactBreakingThreshold)
|
||||
:m_sphere(sphere),
|
||||
m_triangle(triangle)
|
||||
m_triangle(triangle),
|
||||
m_contactBreakingThreshold(contactBreakingThreshold)
|
||||
{
|
||||
|
||||
}
|
||||
@ -40,7 +41,7 @@ void SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Res
|
||||
//move sphere into triangle space
|
||||
btTransform sphereInTr = transformB.inverseTimes(transformA);
|
||||
|
||||
if (collide(sphereInTr.getOrigin(),point,normal,depth,timeOfImpact))
|
||||
if (collide(sphereInTr.getOrigin(),point,normal,depth,timeOfImpact,m_contactBreakingThreshold))
|
||||
{
|
||||
if (swapResults)
|
||||
{
|
||||
@ -93,7 +94,7 @@ bool SphereTriangleDetector::facecontains(const btVector3 &p,const btVector3* ve
|
||||
}
|
||||
|
||||
///combined discrete/continuous sphere-triangle
|
||||
bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact)
|
||||
bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold)
|
||||
{
|
||||
|
||||
const btVector3* vertices = &m_triangle->getVertexPtr(0);
|
||||
@ -115,10 +116,7 @@ bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &po
|
||||
normal *= btScalar(-1.);
|
||||
}
|
||||
|
||||
///todo: move this gContactBreakingThreshold into a proper structure
|
||||
extern btScalar gContactBreakingThreshold;
|
||||
|
||||
btScalar contactMargin = gContactBreakingThreshold;
|
||||
btScalar contactMargin = contactBreakingThreshold;
|
||||
bool isInsideContactPlane = distanceFromPlane < r + contactMargin;
|
||||
bool isInsideShellPlane = distanceFromPlane < r;
|
||||
|
||||
@ -140,8 +138,8 @@ bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &po
|
||||
btVector3 nearestOnEdge;
|
||||
for (int i = 0; i < m_triangle->getNumEdges(); i++) {
|
||||
|
||||
btPoint3 pa;
|
||||
btPoint3 pb;
|
||||
btVector3 pa;
|
||||
btVector3 pb;
|
||||
|
||||
m_triangle->getEdge(i,pa,pb);
|
||||
|
||||
|
@ -17,7 +17,7 @@ subject to the following restrictions:
|
||||
#define SPHERE_TRIANGLE_DETECTOR_H
|
||||
|
||||
#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
|
||||
#include "LinearMath/btPoint3.h"
|
||||
|
||||
|
||||
|
||||
class btSphereShape;
|
||||
@ -30,19 +30,19 @@ struct SphereTriangleDetector : public btDiscreteCollisionDetectorInterface
|
||||
{
|
||||
virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false);
|
||||
|
||||
SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle);
|
||||
SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle, btScalar contactBreakingThreshold);
|
||||
|
||||
virtual ~SphereTriangleDetector() {};
|
||||
|
||||
private:
|
||||
|
||||
bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact);
|
||||
bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold);
|
||||
bool pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p );
|
||||
bool facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal);
|
||||
|
||||
btSphereShape* m_sphere;
|
||||
btTriangleShape* m_triangle;
|
||||
|
||||
btScalar m_contactBreakingThreshold;
|
||||
|
||||
};
|
||||
#endif //SPHERE_TRIANGLE_DETECTOR_H
|
||||
|
47
extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp
vendored
Normal file
47
extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
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 "btActivatingCollisionAlgorithm.h"
|
||||
#include "btCollisionDispatcher.h"
|
||||
#include "btCollisionObject.h"
|
||||
|
||||
btActivatingCollisionAlgorithm::btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci)
|
||||
:btCollisionAlgorithm(ci)
|
||||
//,
|
||||
//m_colObj0(0),
|
||||
//m_colObj1(0)
|
||||
{
|
||||
}
|
||||
btActivatingCollisionAlgorithm::btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* colObj0,btCollisionObject* colObj1)
|
||||
:btCollisionAlgorithm(ci)
|
||||
//,
|
||||
//m_colObj0(0),
|
||||
//m_colObj1(0)
|
||||
{
|
||||
// if (ci.m_dispatcher1->needsCollision(colObj0,colObj1))
|
||||
// {
|
||||
// m_colObj0 = colObj0;
|
||||
// m_colObj1 = colObj1;
|
||||
//
|
||||
// m_colObj0->activate();
|
||||
// m_colObj1->activate();
|
||||
// }
|
||||
}
|
||||
|
||||
btActivatingCollisionAlgorithm::~btActivatingCollisionAlgorithm()
|
||||
{
|
||||
// m_colObj0->activate();
|
||||
// m_colObj1->activate();
|
||||
}
|
36
extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h
vendored
Normal file
36
extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
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_ACTIVATING_COLLISION_ALGORITHM_H
|
||||
#define __BT_ACTIVATING_COLLISION_ALGORITHM_H
|
||||
|
||||
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
|
||||
|
||||
///This class is not enabled yet (work-in-progress) to more aggressively activate objects.
|
||||
class btActivatingCollisionAlgorithm : public btCollisionAlgorithm
|
||||
{
|
||||
// btCollisionObject* m_colObj0;
|
||||
// btCollisionObject* m_colObj1;
|
||||
|
||||
public:
|
||||
|
||||
btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci);
|
||||
|
||||
btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* colObj0,btCollisionObject* colObj1);
|
||||
|
||||
virtual ~btActivatingCollisionAlgorithm();
|
||||
|
||||
};
|
||||
#endif //__BT_ACTIVATING_COLLISION_ALGORITHM_H
|
@ -22,7 +22,7 @@ subject to the following restrictions:
|
||||
#define USE_PERSISTENT_CONTACTS 1
|
||||
|
||||
btBoxBoxCollisionAlgorithm::btBoxBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* obj0,btCollisionObject* obj1)
|
||||
: btCollisionAlgorithm(ci),
|
||||
: btActivatingCollisionAlgorithm(ci,obj0,obj1),
|
||||
m_ownManifold(false),
|
||||
m_manifoldPtr(mf)
|
||||
{
|
||||
|
@ -16,7 +16,7 @@ subject to the following restrictions:
|
||||
#ifndef BOX_BOX__COLLISION_ALGORITHM_H
|
||||
#define BOX_BOX__COLLISION_ALGORITHM_H
|
||||
|
||||
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
|
||||
#include "btActivatingCollisionAlgorithm.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
|
||||
@ -24,14 +24,14 @@ subject to the following restrictions:
|
||||
class btPersistentManifold;
|
||||
|
||||
///box-box collision detection
|
||||
class btBoxBoxCollisionAlgorithm : public btCollisionAlgorithm
|
||||
class btBoxBoxCollisionAlgorithm : public btActivatingCollisionAlgorithm
|
||||
{
|
||||
bool m_ownManifold;
|
||||
btPersistentManifold* m_manifoldPtr;
|
||||
|
||||
public:
|
||||
btBoxBoxCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
|
||||
: btCollisionAlgorithm(ci) {}
|
||||
: btActivatingCollisionAlgorithm(ci) {}
|
||||
|
||||
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
|
@ -207,7 +207,13 @@ void cullPoints2 (int n, btScalar p[], int m, int i0, int iret[])
|
||||
cy += q*(p[i*2+1]+p[i*2+3]);
|
||||
}
|
||||
q = p[n*2-2]*p[1] - p[0]*p[n*2-1];
|
||||
a = 1.f/(btScalar(3.0)*(a+q));
|
||||
if (btFabs(a+q) > SIMD_EPSILON)
|
||||
{
|
||||
a = 1.f/(btScalar(3.0)*(a+q));
|
||||
} else
|
||||
{
|
||||
a=1e30f;
|
||||
}
|
||||
cx = a*(cx + q*(p[n*2-2]+p[0]));
|
||||
cy = a*(cy + q*(p[n*2-1]+p[1]));
|
||||
}
|
||||
@ -226,9 +232,9 @@ void cullPoints2 (int n, btScalar p[], int m, int i0, int iret[])
|
||||
a = btScalar(j)*(2*M__PI/m) + A[i0];
|
||||
if (a > M__PI) a -= 2*M__PI;
|
||||
btScalar maxdiff=1e9,diff;
|
||||
#if defined(DEBUG) || defined (_DEBUG)
|
||||
*iret = i0; // iret is not allowed to keep this value
|
||||
#endif
|
||||
|
||||
*iret = i0; // iret is not allowed to keep this value, but it sometimes does, when diff=#QNAN0
|
||||
|
||||
for (i=0; i<n; i++) {
|
||||
if (avail[i]) {
|
||||
diff = btFabs (A[i]-a);
|
||||
|
@ -22,7 +22,7 @@ class btPoolAllocator;
|
||||
|
||||
///btCollisionConfiguration allows to configure Bullet collision detection
|
||||
///stack allocator size, default collision algorithms and persistent manifold pool size
|
||||
///todo: describe the meaning
|
||||
///@todo: describe the meaning
|
||||
class btCollisionConfiguration
|
||||
{
|
||||
|
||||
|
@ -17,7 +17,6 @@ subject to the following restrictions:
|
||||
#define COLLISION_CREATE_FUNC
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
|
||||
class btCollisionAlgorithm;
|
||||
class btCollisionObject;
|
||||
|
||||
|
@ -52,12 +52,12 @@ btCollisionDispatcher::btCollisionDispatcher (btCollisionConfiguration* collisio
|
||||
for (int j=0;j<MAX_BROADPHASE_COLLISION_TYPES;j++)
|
||||
{
|
||||
m_doubleDispatch[i][j] = m_collisionConfiguration->getCollisionAlgorithmCreateFunc(i,j);
|
||||
assert(m_doubleDispatch[i][j]);
|
||||
btAssert(m_doubleDispatch[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void btCollisionDispatcher::registerCollisionCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc)
|
||||
@ -78,7 +78,13 @@ btPersistentManifold* btCollisionDispatcher::getNewManifold(void* b0,void* b1)
|
||||
|
||||
btCollisionObject* body0 = (btCollisionObject*)b0;
|
||||
btCollisionObject* body1 = (btCollisionObject*)b1;
|
||||
|
||||
|
||||
//test for Bullet 2.74: use a relative contact breaking threshold without clamping against 'gContactBreakingThreshold'
|
||||
//btScalar contactBreakingThreshold = btMin(gContactBreakingThreshold,btMin(body0->getCollisionShape()->getContactBreakingThreshold(),body1->getCollisionShape()->getContactBreakingThreshold()));
|
||||
btScalar contactBreakingThreshold = btMin(body0->getCollisionShape()->getContactBreakingThreshold(),body1->getCollisionShape()->getContactBreakingThreshold());
|
||||
|
||||
btScalar contactProcessingThreshold = btMin(body0->getContactProcessingThreshold(),body1->getContactProcessingThreshold());
|
||||
|
||||
void* mem = 0;
|
||||
|
||||
if (m_persistentManifoldPoolAllocator->getFreeCount())
|
||||
@ -89,7 +95,7 @@ btPersistentManifold* btCollisionDispatcher::getNewManifold(void* b0,void* b1)
|
||||
mem = btAlignedAlloc(sizeof(btPersistentManifold),16);
|
||||
|
||||
}
|
||||
btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0);
|
||||
btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0,contactBreakingThreshold,contactProcessingThreshold);
|
||||
manifold->m_index1a = m_manifoldsPtr.size();
|
||||
m_manifoldsPtr.push_back(manifold);
|
||||
|
||||
@ -144,7 +150,6 @@ btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(btCollisionObject* bo
|
||||
|
||||
|
||||
|
||||
|
||||
bool btCollisionDispatcher::needsResponse(btCollisionObject* body0,btCollisionObject* body1)
|
||||
{
|
||||
//here you can do filtering
|
||||
@ -158,8 +163,8 @@ bool btCollisionDispatcher::needsResponse(btCollisionObject* body0,btCollisionOb
|
||||
|
||||
bool btCollisionDispatcher::needsCollision(btCollisionObject* body0,btCollisionObject* body1)
|
||||
{
|
||||
assert(body0);
|
||||
assert(body1);
|
||||
btAssert(body0);
|
||||
btAssert(body1);
|
||||
|
||||
bool needsCollision = true;
|
||||
|
||||
|
@ -19,6 +19,7 @@ subject to the following restrictions:
|
||||
btCollisionObject::btCollisionObject()
|
||||
: m_anisotropicFriction(1.f,1.f,1.f),
|
||||
m_hasAnisotropicFriction(false),
|
||||
m_contactProcessingThreshold(0.f),
|
||||
m_broadphaseHandle(0),
|
||||
m_collisionShape(0),
|
||||
m_rootCollisionShape(0),
|
||||
|
@ -29,8 +29,11 @@ struct btBroadphaseProxy;
|
||||
class btCollisionShape;
|
||||
#include "LinearMath/btMotionState.h"
|
||||
#include "LinearMath/btAlignedAllocator.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
|
||||
typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
|
||||
|
||||
|
||||
/// btCollisionObject can be used to manage collision detection objects.
|
||||
/// btCollisionObject maintains all information that is needed for a collision detection: Shape, Transform and AABB proxy.
|
||||
@ -49,8 +52,10 @@ protected:
|
||||
//without destroying the continuous interpolated motion (which uses this interpolation velocities)
|
||||
btVector3 m_interpolationLinearVelocity;
|
||||
btVector3 m_interpolationAngularVelocity;
|
||||
|
||||
btVector3 m_anisotropicFriction;
|
||||
bool m_hasAnisotropicFriction;
|
||||
bool m_hasAnisotropicFriction;
|
||||
btScalar m_contactProcessingThreshold;
|
||||
|
||||
btBroadphaseProxy* m_broadphaseHandle;
|
||||
btCollisionShape* m_collisionShape;
|
||||
@ -74,7 +79,7 @@ protected:
|
||||
///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer
|
||||
void* m_userObjectPointer;
|
||||
|
||||
///m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody etc.
|
||||
///m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody, btGhostObject etc.
|
||||
///do not assign your own m_internalType unless you write a new dynamics object class.
|
||||
int m_internalType;
|
||||
|
||||
@ -106,14 +111,19 @@ public:
|
||||
CF_STATIC_OBJECT= 1,
|
||||
CF_KINEMATIC_OBJECT= 2,
|
||||
CF_NO_CONTACT_RESPONSE = 4,
|
||||
CF_CUSTOM_MATERIAL_CALLBACK = 8//this allows per-triangle material (friction/restitution)
|
||||
CF_CUSTOM_MATERIAL_CALLBACK = 8,//this allows per-triangle material (friction/restitution)
|
||||
CF_CHARACTER_OBJECT = 16
|
||||
};
|
||||
|
||||
enum CollisionObjectTypes
|
||||
{
|
||||
CO_COLLISION_OBJECT =1,
|
||||
CO_RIGID_BODY,
|
||||
CO_SOFT_BODY
|
||||
///CO_GHOST_OBJECT keeps track of all objects overlapping its AABB and that pass its collision filter
|
||||
///It is useful for collision sensors, explosion objects, character controller etc.
|
||||
CO_GHOST_OBJECT,
|
||||
CO_SOFT_BODY,
|
||||
CO_HF_FLUID
|
||||
};
|
||||
|
||||
SIMD_FORCE_INLINE bool mergesSimulationIslands() const
|
||||
@ -136,6 +146,16 @@ public:
|
||||
return m_hasAnisotropicFriction;
|
||||
}
|
||||
|
||||
///the constraint solver can discard solving contacts, if the distance is above this threshold. 0 by default.
|
||||
///Note that using contacts with positive distance can improve stability. It increases, however, the chance of colliding with degerate contacts, such as 'interior' triangle edges
|
||||
void setContactProcessingThreshold( btScalar contactProcessingThreshold)
|
||||
{
|
||||
m_contactProcessingThreshold = contactProcessingThreshold;
|
||||
}
|
||||
btScalar getContactProcessingThreshold() const
|
||||
{
|
||||
return m_contactProcessingThreshold;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE bool isStaticObject() const {
|
||||
return (m_collisionFlags & CF_STATIC_OBJECT) != 0;
|
||||
@ -193,7 +213,7 @@ public:
|
||||
m_collisionShape = collisionShape;
|
||||
}
|
||||
|
||||
int getActivationState() const { return m_activationState1;}
|
||||
SIMD_FORCE_INLINE int getActivationState() const { return m_activationState1;}
|
||||
|
||||
void setActivationState(int newState);
|
||||
|
||||
@ -210,7 +230,7 @@ public:
|
||||
|
||||
void activate(bool forceActivation = false);
|
||||
|
||||
inline bool isActive() const
|
||||
SIMD_FORCE_INLINE bool isActive() const
|
||||
{
|
||||
return ((getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION));
|
||||
}
|
||||
@ -254,12 +274,12 @@ public:
|
||||
}
|
||||
|
||||
|
||||
btBroadphaseProxy* getBroadphaseHandle()
|
||||
SIMD_FORCE_INLINE btBroadphaseProxy* getBroadphaseHandle()
|
||||
{
|
||||
return m_broadphaseHandle;
|
||||
}
|
||||
|
||||
const btBroadphaseProxy* getBroadphaseHandle() const
|
||||
SIMD_FORCE_INLINE const btBroadphaseProxy* getBroadphaseHandle() const
|
||||
{
|
||||
return m_broadphaseHandle;
|
||||
}
|
||||
@ -305,7 +325,7 @@ public:
|
||||
return m_interpolationAngularVelocity;
|
||||
}
|
||||
|
||||
const int getIslandTag() const
|
||||
SIMD_FORCE_INLINE int getIslandTag() const
|
||||
{
|
||||
return m_islandTag1;
|
||||
}
|
||||
@ -315,7 +335,7 @@ public:
|
||||
m_islandTag1 = tag;
|
||||
}
|
||||
|
||||
const int getCompanionId() const
|
||||
SIMD_FORCE_INLINE int getCompanionId() const
|
||||
{
|
||||
return m_companionId;
|
||||
}
|
||||
@ -325,7 +345,7 @@ public:
|
||||
m_companionId = id;
|
||||
}
|
||||
|
||||
const btScalar getHitFraction() const
|
||||
SIMD_FORCE_INLINE btScalar getHitFraction() const
|
||||
{
|
||||
return m_hitFraction;
|
||||
}
|
||||
@ -336,7 +356,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
const int getCollisionFlags() const
|
||||
SIMD_FORCE_INLINE int getCollisionFlags() const
|
||||
{
|
||||
return m_collisionFlags;
|
||||
}
|
||||
|
@ -32,6 +32,9 @@ subject to the following restrictions:
|
||||
#include "LinearMath/btQuickprof.h"
|
||||
#include "LinearMath/btStackAlloc.h"
|
||||
|
||||
//#define USE_BRUTEFORCE_RAYBROADPHASE 1
|
||||
//RECALCULATE_AABB is slower, but benefit is that you don't need to call 'stepSimulation' or 'updateAabbs' before using a rayTest
|
||||
//#define RECALCULATE_AABB_RAYCAST 1
|
||||
|
||||
//When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor)
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
|
||||
@ -66,6 +69,7 @@ btCollisionWorld::~btCollisionWorld()
|
||||
//
|
||||
getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1);
|
||||
getBroadphase()->destroyProxy(bp,m_dispatcher1);
|
||||
collisionObject->setBroadphaseHandle(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,6 +115,41 @@ void btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,sho
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void btCollisionWorld::updateSingleAabb(btCollisionObject* colObj)
|
||||
{
|
||||
btVector3 minAabb,maxAabb;
|
||||
colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
|
||||
//need to increase the aabb for contact thresholds
|
||||
btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold);
|
||||
minAabb -= contactThreshold;
|
||||
maxAabb += contactThreshold;
|
||||
|
||||
btBroadphaseInterface* bp = (btBroadphaseInterface*)m_broadphasePairCache;
|
||||
|
||||
//moving objects should be moderately sized, probably something wrong if not
|
||||
if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < btScalar(1e12)))
|
||||
{
|
||||
bp->setAabb(colObj->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1);
|
||||
} else
|
||||
{
|
||||
//something went wrong, investigate
|
||||
//this assert is unwanted in 3D modelers (danger of loosing work)
|
||||
colObj->setActivationState(DISABLE_SIMULATION);
|
||||
|
||||
static bool reportMe = true;
|
||||
if (reportMe && m_debugDrawer)
|
||||
{
|
||||
reportMe = false;
|
||||
m_debugDrawer->reportErrorWarning("Overflow in AABB, object removed from simulation");
|
||||
m_debugDrawer->reportErrorWarning("If you can reproduce this, please email bugs@continuousphysics.com\n");
|
||||
m_debugDrawer->reportErrorWarning("Please include above information, your Platform, version of OS.\n");
|
||||
m_debugDrawer->reportErrorWarning("Thanks.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void btCollisionWorld::updateAabbs()
|
||||
@ -125,38 +164,9 @@ void btCollisionWorld::updateAabbs()
|
||||
//only update aabb of active objects
|
||||
if (colObj->isActive())
|
||||
{
|
||||
btPoint3 minAabb,maxAabb;
|
||||
colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
|
||||
//need to increase the aabb for contact thresholds
|
||||
btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold);
|
||||
minAabb -= contactThreshold;
|
||||
maxAabb += contactThreshold;
|
||||
|
||||
btBroadphaseInterface* bp = (btBroadphaseInterface*)m_broadphasePairCache;
|
||||
|
||||
//moving objects should be moderately sized, probably something wrong if not
|
||||
if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < btScalar(1e12)))
|
||||
{
|
||||
bp->setAabb(colObj->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1);
|
||||
} else
|
||||
{
|
||||
//something went wrong, investigate
|
||||
//this assert is unwanted in 3D modelers (danger of loosing work)
|
||||
colObj->setActivationState(DISABLE_SIMULATION);
|
||||
|
||||
static bool reportMe = true;
|
||||
if (reportMe && m_debugDrawer)
|
||||
{
|
||||
reportMe = false;
|
||||
m_debugDrawer->reportErrorWarning("Overflow in AABB, object removed from simulation");
|
||||
m_debugDrawer->reportErrorWarning("If you can reproduce this, please email bugs@continuousphysics.com\n");
|
||||
m_debugDrawer->reportErrorWarning("Please include above information, your Platform, version of OS.\n");
|
||||
m_debugDrawer->reportErrorWarning("Thanks.\n");
|
||||
}
|
||||
}
|
||||
updateSingleAabb(colObj);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -226,6 +236,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
|
||||
|
||||
if (collisionShape->isConvex())
|
||||
{
|
||||
// BT_PROFILE("rayTestConvex");
|
||||
btConvexCast::CastResult castResult;
|
||||
castResult.m_fraction = resultCallback.m_closestHitFraction;
|
||||
|
||||
@ -269,6 +280,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
|
||||
} else {
|
||||
if (collisionShape->isConcave())
|
||||
{
|
||||
// BT_PROFILE("rayTestConcave");
|
||||
if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
|
||||
{
|
||||
///optimized version for btBvhTriangleMeshShape
|
||||
@ -286,7 +298,8 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
|
||||
|
||||
BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
|
||||
btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh):
|
||||
btTriangleRaycastCallback(from,to),
|
||||
//@BP Mod
|
||||
btTriangleRaycastCallback(from,to, resultCallback->m_flags),
|
||||
m_resultCallback(resultCallback),
|
||||
m_collisionObject(collisionObject),
|
||||
m_triangleMesh(triangleMesh)
|
||||
@ -317,7 +330,8 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
|
||||
triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal);
|
||||
} else
|
||||
{
|
||||
btTriangleMeshShape* triangleMesh = (btTriangleMeshShape*)collisionShape;
|
||||
//generic (slower) case
|
||||
btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
|
||||
|
||||
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
|
||||
|
||||
@ -330,11 +344,12 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
|
||||
{
|
||||
btCollisionWorld::RayResultCallback* m_resultCallback;
|
||||
btCollisionObject* m_collisionObject;
|
||||
btTriangleMeshShape* m_triangleMesh;
|
||||
btConcaveShape* m_triangleMesh;
|
||||
|
||||
BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
|
||||
btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh):
|
||||
btTriangleRaycastCallback(from,to),
|
||||
btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape* triangleMesh):
|
||||
//@BP Mod
|
||||
btTriangleRaycastCallback(from,to, resultCallback->m_flags),
|
||||
m_resultCallback(resultCallback),
|
||||
m_collisionObject(collisionObject),
|
||||
m_triangleMesh(triangleMesh)
|
||||
@ -363,7 +378,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
|
||||
};
|
||||
|
||||
|
||||
BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh);
|
||||
BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,concaveShape);
|
||||
rcb.m_hitFraction = resultCallback.m_closestHitFraction;
|
||||
|
||||
btVector3 rayAabbMinLocal = rayFromLocal;
|
||||
@ -371,10 +386,11 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
|
||||
btVector3 rayAabbMaxLocal = rayFromLocal;
|
||||
rayAabbMaxLocal.setMax(rayToLocal);
|
||||
|
||||
triangleMesh->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
|
||||
concaveShape->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
|
||||
}
|
||||
} else {
|
||||
//todo: use AABB tree or other BVH acceleration structure!
|
||||
// BT_PROFILE("rayTestCompound");
|
||||
///@todo: use AABB tree or other BVH acceleration structure, see btDbvt
|
||||
if (collisionShape->isCompound())
|
||||
{
|
||||
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
|
||||
@ -408,9 +424,10 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
|
||||
{
|
||||
if (collisionShape->isConvex())
|
||||
{
|
||||
//BT_PROFILE("convexSweepConvex");
|
||||
btConvexCast::CastResult castResult;
|
||||
castResult.m_allowedPenetration = allowedPenetration;
|
||||
castResult.m_fraction = btScalar(1.);//??
|
||||
castResult.m_fraction = resultCallback.m_closestHitFraction;//btScalar(1.);//??
|
||||
|
||||
btConvexShape* convexShape = (btConvexShape*) collisionShape;
|
||||
btVoronoiSimplexSolver simplexSolver;
|
||||
@ -452,6 +469,7 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
|
||||
{
|
||||
if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
|
||||
{
|
||||
//BT_PROFILE("convexSweepbtBvhTriangleMesh");
|
||||
btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
|
||||
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
|
||||
btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
|
||||
@ -508,7 +526,8 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
|
||||
triangleMesh->performConvexcast(&tccb,convexFromLocal,convexToLocal,boxMinLocal, boxMaxLocal);
|
||||
} else
|
||||
{
|
||||
btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
|
||||
//BT_PROFILE("convexSweepConcave");
|
||||
btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
|
||||
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
|
||||
btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
|
||||
btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
|
||||
@ -520,10 +539,10 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
|
||||
{
|
||||
btCollisionWorld::ConvexResultCallback* m_resultCallback;
|
||||
btCollisionObject* m_collisionObject;
|
||||
btTriangleMeshShape* m_triangleMesh;
|
||||
btConcaveShape* m_triangleMesh;
|
||||
|
||||
BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
|
||||
btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh, const btTransform& triangleToWorld):
|
||||
btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& triangleToWorld):
|
||||
btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
|
||||
m_resultCallback(resultCallback),
|
||||
m_collisionObject(collisionObject),
|
||||
@ -556,7 +575,7 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
|
||||
|
||||
};
|
||||
|
||||
BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,triangleMesh, colObjWorldTransform);
|
||||
BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,concaveShape, colObjWorldTransform);
|
||||
tccb.m_hitFraction = resultCallback.m_closestHitFraction;
|
||||
btVector3 boxMinLocal, boxMaxLocal;
|
||||
castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
|
||||
@ -567,12 +586,13 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
|
||||
rayAabbMaxLocal.setMax(convexToLocal);
|
||||
rayAabbMinLocal += boxMinLocal;
|
||||
rayAabbMaxLocal += boxMaxLocal;
|
||||
triangleMesh->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal);
|
||||
concaveShape->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal);
|
||||
}
|
||||
} else {
|
||||
//todo: use AABB tree or other BVH acceleration structure!
|
||||
///@todo : use AABB tree or other BVH acceleration structure!
|
||||
if (collisionShape->isCompound())
|
||||
{
|
||||
BT_PROFILE("convexSweepCompound");
|
||||
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
|
||||
int i=0;
|
||||
for (i=0;i<compoundShape->getNumChildShapes();i++)
|
||||
@ -596,51 +616,173 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
|
||||
}
|
||||
}
|
||||
|
||||
void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
|
||||
|
||||
struct btSingleRayCallback : public btBroadphaseRayCallback
|
||||
{
|
||||
|
||||
btVector3 m_rayFromWorld;
|
||||
btVector3 m_rayToWorld;
|
||||
btTransform m_rayFromTrans;
|
||||
btTransform m_rayToTrans;
|
||||
btVector3 m_hitNormal;
|
||||
|
||||
btTransform rayFromTrans,rayToTrans;
|
||||
rayFromTrans.setIdentity();
|
||||
rayFromTrans.setOrigin(rayFromWorld);
|
||||
rayToTrans.setIdentity();
|
||||
const btCollisionWorld* m_world;
|
||||
btCollisionWorld::RayResultCallback& m_resultCallback;
|
||||
|
||||
rayToTrans.setOrigin(rayToWorld);
|
||||
|
||||
/// go over all objects, and if the ray intersects their aabb, do a ray-shape query using convexCaster (CCD)
|
||||
|
||||
int i;
|
||||
for (i=0;i<m_collisionObjects.size();i++)
|
||||
btSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btCollisionWorld* world,btCollisionWorld::RayResultCallback& resultCallback)
|
||||
:m_rayFromWorld(rayFromWorld),
|
||||
m_rayToWorld(rayToWorld),
|
||||
m_world(world),
|
||||
m_resultCallback(resultCallback)
|
||||
{
|
||||
///terminate further ray tests, once the closestHitFraction reached zero
|
||||
if (resultCallback.m_closestHitFraction == btScalar(0.f))
|
||||
break;
|
||||
m_rayFromTrans.setIdentity();
|
||||
m_rayFromTrans.setOrigin(m_rayFromWorld);
|
||||
m_rayToTrans.setIdentity();
|
||||
m_rayToTrans.setOrigin(m_rayToWorld);
|
||||
|
||||
btCollisionObject* collisionObject= m_collisionObjects[i];
|
||||
//only perform raycast if filterMask matches
|
||||
if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
|
||||
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
|
||||
btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
|
||||
collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
|
||||
btVector3 rayDir = (rayToWorld-rayFromWorld);
|
||||
|
||||
btScalar hitLambda = resultCallback.m_closestHitFraction;
|
||||
btVector3 hitNormal;
|
||||
if (btRayAabb(rayFromWorld,rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
|
||||
{
|
||||
rayTestSingle(rayFromTrans,rayToTrans,
|
||||
collisionObject,
|
||||
collisionObject->getCollisionShape(),
|
||||
collisionObject->getWorldTransform(),
|
||||
resultCallback);
|
||||
}
|
||||
}
|
||||
rayDir.normalize ();
|
||||
///what about division by zero? --> just set rayDirection[i] to INF/1e30
|
||||
m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
|
||||
m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
|
||||
m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
|
||||
m_signs[0] = m_rayDirectionInverse[0] < 0.0;
|
||||
m_signs[1] = m_rayDirectionInverse[1] < 0.0;
|
||||
m_signs[2] = m_rayDirectionInverse[2] < 0.0;
|
||||
|
||||
m_lambda_max = rayDir.dot(m_rayToWorld-m_rayFromWorld);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual bool process(const btBroadphaseProxy* proxy)
|
||||
{
|
||||
///terminate further ray tests, once the closestHitFraction reached zero
|
||||
if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
|
||||
return false;
|
||||
|
||||
btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
|
||||
|
||||
//only perform raycast if filterMask matches
|
||||
if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
|
||||
{
|
||||
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
|
||||
//btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
|
||||
#if 0
|
||||
#ifdef RECALCULATE_AABB
|
||||
btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
|
||||
collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
|
||||
#else
|
||||
//getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
|
||||
const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
|
||||
const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
|
||||
#endif
|
||||
#endif
|
||||
//btScalar hitLambda = m_resultCallback.m_closestHitFraction;
|
||||
//culling already done by broadphase
|
||||
//if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
|
||||
{
|
||||
m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans,
|
||||
collisionObject,
|
||||
collisionObject->getCollisionShape(),
|
||||
collisionObject->getWorldTransform(),
|
||||
m_resultCallback);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
|
||||
{
|
||||
BT_PROFILE("rayTest");
|
||||
/// use the broadphase to accelerate the search for objects, based on their aabb
|
||||
/// and for each object with ray-aabb overlap, perform an exact ray test
|
||||
btSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback);
|
||||
|
||||
#ifndef USE_BRUTEFORCE_RAYBROADPHASE
|
||||
m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB);
|
||||
#else
|
||||
for (int i=0;i<this->getNumCollisionObjects();i++)
|
||||
{
|
||||
rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
|
||||
}
|
||||
#endif //USE_BRUTEFORCE_RAYBROADPHASE
|
||||
|
||||
}
|
||||
|
||||
void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback) const
|
||||
|
||||
struct btSingleSweepCallback : public btBroadphaseRayCallback
|
||||
{
|
||||
|
||||
btTransform m_convexFromTrans;
|
||||
btTransform m_convexToTrans;
|
||||
btVector3 m_hitNormal;
|
||||
const btCollisionWorld* m_world;
|
||||
btCollisionWorld::ConvexResultCallback& m_resultCallback;
|
||||
btScalar m_allowedCcdPenetration;
|
||||
const btConvexShape* m_castShape;
|
||||
|
||||
|
||||
btSingleSweepCallback(const btConvexShape* castShape, const btTransform& convexFromTrans,const btTransform& convexToTrans,const btCollisionWorld* world,btCollisionWorld::ConvexResultCallback& resultCallback,btScalar allowedPenetration)
|
||||
:m_convexFromTrans(convexFromTrans),
|
||||
m_convexToTrans(convexToTrans),
|
||||
m_world(world),
|
||||
m_resultCallback(resultCallback),
|
||||
m_allowedCcdPenetration(allowedPenetration),
|
||||
m_castShape(castShape)
|
||||
{
|
||||
btVector3 unnormalizedRayDir = (m_convexToTrans.getOrigin()-m_convexFromTrans.getOrigin());
|
||||
btVector3 rayDir = unnormalizedRayDir.normalized();
|
||||
///what about division by zero? --> just set rayDirection[i] to INF/1e30
|
||||
m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
|
||||
m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
|
||||
m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
|
||||
m_signs[0] = m_rayDirectionInverse[0] < 0.0;
|
||||
m_signs[1] = m_rayDirectionInverse[1] < 0.0;
|
||||
m_signs[2] = m_rayDirectionInverse[2] < 0.0;
|
||||
|
||||
m_lambda_max = rayDir.dot(unnormalizedRayDir);
|
||||
|
||||
}
|
||||
|
||||
virtual bool process(const btBroadphaseProxy* proxy)
|
||||
{
|
||||
///terminate further convex sweep tests, once the closestHitFraction reached zero
|
||||
if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
|
||||
return false;
|
||||
|
||||
btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
|
||||
|
||||
//only perform raycast if filterMask matches
|
||||
if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
|
||||
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
|
||||
m_world->objectQuerySingle(m_castShape, m_convexFromTrans,m_convexToTrans,
|
||||
collisionObject,
|
||||
collisionObject->getCollisionShape(),
|
||||
collisionObject->getWorldTransform(),
|
||||
m_resultCallback,
|
||||
m_allowedCcdPenetration);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const
|
||||
{
|
||||
|
||||
BT_PROFILE("convexSweepTest");
|
||||
/// use the broadphase to accelerate the search for objects, based on their aabb
|
||||
/// and for each object with ray-aabb overlap, perform an exact ray test
|
||||
/// unfortunately the implementation for rayTest and convexSweepTest duplicated, albeit practically identical
|
||||
|
||||
|
||||
|
||||
btTransform convexFromTrans,convexToTrans;
|
||||
convexFromTrans = convexFromWorld;
|
||||
convexToTrans = convexToWorld;
|
||||
@ -649,12 +791,21 @@ void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btT
|
||||
{
|
||||
btVector3 linVel, angVel;
|
||||
btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0, linVel, angVel);
|
||||
btVector3 zeroLinVel;
|
||||
zeroLinVel.setValue(0,0,0);
|
||||
btTransform R;
|
||||
R.setIdentity ();
|
||||
R.setRotation (convexFromTrans.getRotation());
|
||||
castShape->calculateTemporalAabb (R, linVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
|
||||
castShape->calculateTemporalAabb (R, zeroLinVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
|
||||
}
|
||||
|
||||
#ifndef USE_BRUTEFORCE_RAYBROADPHASE
|
||||
|
||||
btSingleSweepCallback convexCB(castShape,convexFromWorld,convexToWorld,this,resultCallback,allowedCcdPenetration);
|
||||
|
||||
m_broadphasePairCache->rayTest(convexFromTrans.getOrigin(),convexToTrans.getOrigin(),convexCB,castShapeAabbMin,castShapeAabbMax);
|
||||
|
||||
#else
|
||||
/// go over all objects, and if the ray intersects their aabb + cast shape aabb,
|
||||
// do a ray-shape query using convexCaster (CCD)
|
||||
int i;
|
||||
@ -676,9 +827,9 @@ void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btT
|
||||
collisionObject->getCollisionShape(),
|
||||
collisionObject->getWorldTransform(),
|
||||
resultCallback,
|
||||
getDispatchInfo().m_allowedCcdPenetration);
|
||||
allowedCcdPenetration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif //USE_BRUTEFORCE_RAYBROADPHASE
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://bulletphysics.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.
|
||||
@ -22,39 +22,39 @@ subject to the following restrictions:
|
||||
*
|
||||
* Bullet is a Collision Detection and Rigid Body Dynamics Library. The Library is Open Source and free for commercial use, under the ZLib license ( http://opensource.org/licenses/zlib-license.php ).
|
||||
*
|
||||
* There is the Physics Forum for Feedback and bteral Collision Detection and Physics discussions.
|
||||
* Please visit http://www.continuousphysics.com/Bullet/phpBB2/index.php
|
||||
* There is the Physics Forum for feedback and general Collision Detection and Physics discussions.
|
||||
* Please visit http://www.bulletphysics.com
|
||||
*
|
||||
* @section install_sec Installation
|
||||
*
|
||||
* @subsection step1 Step 1: Download
|
||||
* You can download the Bullet Physics Library from our website: http://www.continuousphysics.com/Bullet/
|
||||
* You can download the Bullet Physics Library from the Google Code repository: http://code.google.com/p/bullet/downloads/list
|
||||
* @subsection step2 Step 2: Building
|
||||
* Bullet comes with autogenerated Project Files for Microsoft Visual Studio 6, 7, 7.1 and 8.
|
||||
* The main Workspace/Solution is located in Bullet/msvc/8/wksbullet.sln (replace 8 with your version).
|
||||
*
|
||||
* Under other platforms, like Linux or Mac OS-X, Bullet can be build using either using cmake, http://www.cmake.org, or jam, http://www.perforce.com/jam/jam.html . cmake can autogenerate Xcode, KDevelop, MSVC and other build systems. just run cmake . in the root of Bullet.
|
||||
* Under other platforms, like Linux or Mac OS-X, Bullet can be build using either using make, cmake, http://www.cmake.org , or jam, http://www.perforce.com/jam/jam.html . cmake can autogenerate Xcode, KDevelop, MSVC and other build systems. just run cmake . in the root of Bullet.
|
||||
* So if you are not using MSVC or cmake, you can run ./autogen.sh ./configure to create both Makefile and Jamfile and then run make or jam.
|
||||
* Jam is a build system that can build the library, demos and also autogenerate the MSVC Project Files.
|
||||
* So if you are not using MSVC, you can run configure and jam .
|
||||
* If you don't have jam installed, you can make jam from the included jam-2.5 sources, or download jam from ftp://ftp.perforce.com/pub/jam/
|
||||
* If you don't have jam installed, you can make jam from the included jam-2.5 sources, or download jam from ftp://ftp.perforce.com/jam
|
||||
*
|
||||
* @subsection step3 Step 3: Testing demos
|
||||
* Try to run and experiment with CcdPhysicsDemo executable as a starting point.
|
||||
* Try to run and experiment with BasicDemo executable as a starting point.
|
||||
* Bullet can be used in several ways, as Full Rigid Body simulation, as Collision Detector Library or Low Level / Snippets like the GJK Closest Point calculation.
|
||||
* The Dependencies can be seen in this documentation under Directories
|
||||
*
|
||||
* @subsection step4 Step 4: Integrating in your application, Full Rigid Body Simulation
|
||||
* Check out CcdPhysicsDemo how to create a btDynamicsWorld, btRigidBody and btCollisionShape, Stepping the simulation and synchronizing your graphics object transform.
|
||||
* PLEASE NOTE THE CcdPhysicsEnvironment and CcdPhysicsController is obsolete and will be removed. It has been replaced by classes derived frmo btDynamicsWorld and btRididBody
|
||||
* @subsection step4 Step 4: Integrating in your application, full Rigid Body and Soft Body simulation
|
||||
* Check out BasicDemo how to create a btDynamicsWorld, btRigidBody and btCollisionShape, Stepping the simulation and synchronizing your graphics object transform.
|
||||
* Check out SoftDemo how to use soft body dynamics, using btSoftRigidDynamicsWorld.
|
||||
* @subsection step5 Step 5 : Integrate the Collision Detection Library (without Dynamics and other Extras)
|
||||
* Bullet Collision Detection can also be used without the Dynamics/Extras.
|
||||
* Check out btCollisionWorld and btCollisionObject, and the CollisionInterfaceDemo. Also in Extras/test_BulletOde.cpp there is a sample Collision Detection integration with Open Dynamics Engine, ODE, http://www.ode.org
|
||||
* Check out btCollisionWorld and btCollisionObject, and the CollisionInterfaceDemo.
|
||||
* @subsection step6 Step 6 : Use Snippets like the GJK Closest Point calculation.
|
||||
* Bullet has been designed in a modular way keeping dependencies to a minimum. The ConvexHullDistance demo demonstrates direct use of btGjkPairDetector.
|
||||
*
|
||||
* @section copyright Copyright
|
||||
* Copyright (C) 2005-2007 Erwin Coumans, some contributions Copyright Gino van den Bergen, Christer Ericson, Simon Hobbs, Ricardo Padrela, F Richter(res), Stephane Redon
|
||||
* Special thanks to all visitors of the Bullet Physics forum, and in particular above contributors, Dave Eberle, Dirk Gregorius, Erin Catto, Dave Eberle, Adam Moravanszky,
|
||||
* Copyright (C) 2005-2008 Erwin Coumans, some contributions Copyright Gino van den Bergen, Christer Ericson, Simon Hobbs, Ricardo Padrela, F Richter(res), Stephane Redon
|
||||
* Special thanks to all visitors of the Bullet Physics forum, and in particular above contributors, John McCutchan, Nathanael Presson, Dave Eberle, Dirk Gregorius, Erin Catto, Dave Eberle, Adam Moravanszky,
|
||||
* Pierre Terdiman, Kenny Erleben, Russell Smith, Oliver Strunk, Jan Paul van Waveren, Marten Svanfeldt.
|
||||
*
|
||||
*/
|
||||
@ -71,7 +71,7 @@ class btBroadphaseInterface;
|
||||
#include "LinearMath/btVector3.h"
|
||||
#include "LinearMath/btTransform.h"
|
||||
#include "btCollisionObject.h"
|
||||
#include "btCollisionDispatcher.h" //for definition of btCollisionObjectArray
|
||||
#include "btCollisionDispatcher.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
@ -107,6 +107,11 @@ public:
|
||||
m_broadphasePairCache = pairCache;
|
||||
}
|
||||
|
||||
const btBroadphaseInterface* getBroadphase() const
|
||||
{
|
||||
return m_broadphasePairCache;
|
||||
}
|
||||
|
||||
btBroadphaseInterface* getBroadphase()
|
||||
{
|
||||
return m_broadphasePairCache;
|
||||
@ -128,8 +133,10 @@ public:
|
||||
return m_dispatcher1;
|
||||
}
|
||||
|
||||
virtual void updateAabbs();
|
||||
void updateSingleAabb(btCollisionObject* colObj);
|
||||
|
||||
virtual void updateAabbs();
|
||||
|
||||
virtual void setDebugDrawer(btIDebugDraw* debugDrawer)
|
||||
{
|
||||
m_debugDrawer = debugDrawer;
|
||||
@ -179,6 +186,8 @@ public:
|
||||
btCollisionObject* m_collisionObject;
|
||||
short int m_collisionFilterGroup;
|
||||
short int m_collisionFilterMask;
|
||||
//@BP Mod - Custom flags, currently used to enable backface culling on tri-meshes, see btRaycastCallback
|
||||
unsigned int m_flags;
|
||||
|
||||
virtual ~RayResultCallback()
|
||||
{
|
||||
@ -192,7 +201,9 @@ public:
|
||||
:m_closestHitFraction(btScalar(1.)),
|
||||
m_collisionObject(0),
|
||||
m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter),
|
||||
m_collisionFilterMask(btBroadphaseProxy::AllFilter)
|
||||
m_collisionFilterMask(btBroadphaseProxy::AllFilter),
|
||||
//@BP Mod
|
||||
m_flags(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -347,7 +358,7 @@ public:
|
||||
|
||||
// convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultCallback
|
||||
// This allows for several queries: first hit, all hits, any hit, dependent on the value return by the callback.
|
||||
void convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback) const;
|
||||
void convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration = btScalar(0.)) const;
|
||||
|
||||
|
||||
/// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest.
|
||||
|
@ -19,19 +19,32 @@ subject to the following restrictions:
|
||||
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
|
||||
#include "LinearMath/btIDebugDraw.h"
|
||||
#include "LinearMath/btAabbUtil2.h"
|
||||
#include "btManifoldResult.h"
|
||||
|
||||
btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
|
||||
:btCollisionAlgorithm(ci),
|
||||
:btActivatingCollisionAlgorithm(ci,body0,body1),
|
||||
m_isSwapped(isSwapped),
|
||||
m_sharedManifold(ci.m_manifold)
|
||||
{
|
||||
m_ownsManifold = false;
|
||||
|
||||
btCollisionObject* colObj = m_isSwapped? body1 : body0;
|
||||
btCollisionObject* otherObj = m_isSwapped? body0 : body1;
|
||||
assert (colObj->getCollisionShape()->isCompound());
|
||||
btAssert (colObj->getCollisionShape()->isCompound());
|
||||
|
||||
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
|
||||
m_compoundShapeRevision = compoundShape->getUpdateRevision();
|
||||
|
||||
preallocateChildAlgorithms(body0,body1);
|
||||
}
|
||||
|
||||
void btCompoundCollisionAlgorithm::preallocateChildAlgorithms(btCollisionObject* body0,btCollisionObject* body1)
|
||||
{
|
||||
btCollisionObject* colObj = m_isSwapped? body1 : body0;
|
||||
btCollisionObject* otherObj = m_isSwapped? body0 : body1;
|
||||
btAssert (colObj->getCollisionShape()->isCompound());
|
||||
|
||||
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
|
||||
|
||||
int numChildren = compoundShape->getNumChildShapes();
|
||||
int i;
|
||||
|
||||
@ -46,14 +59,13 @@ m_sharedManifold(ci.m_manifold)
|
||||
btCollisionShape* tmpShape = colObj->getCollisionShape();
|
||||
btCollisionShape* childShape = compoundShape->getChildShape(i);
|
||||
colObj->internalSetTemporaryCollisionShape( childShape );
|
||||
m_childCollisionAlgorithms[i] = ci.m_dispatcher1->findAlgorithm(colObj,otherObj,m_sharedManifold);
|
||||
m_childCollisionAlgorithms[i] = m_dispatcher->findAlgorithm(colObj,otherObj,m_sharedManifold);
|
||||
colObj->internalSetTemporaryCollisionShape( tmpShape );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
btCompoundCollisionAlgorithm::~btCompoundCollisionAlgorithm()
|
||||
void btCompoundCollisionAlgorithm::removeChildAlgorithms()
|
||||
{
|
||||
int numChildren = m_childCollisionAlgorithms.size();
|
||||
int i;
|
||||
@ -67,6 +79,11 @@ btCompoundCollisionAlgorithm::~btCompoundCollisionAlgorithm()
|
||||
}
|
||||
}
|
||||
|
||||
btCompoundCollisionAlgorithm::~btCompoundCollisionAlgorithm()
|
||||
{
|
||||
removeChildAlgorithms();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -167,13 +184,50 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
|
||||
btCollisionObject* colObj = m_isSwapped? body1 : body0;
|
||||
btCollisionObject* otherObj = m_isSwapped? body0 : body1;
|
||||
|
||||
assert (colObj->getCollisionShape()->isCompound());
|
||||
|
||||
|
||||
btAssert (colObj->getCollisionShape()->isCompound());
|
||||
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
|
||||
|
||||
///btCompoundShape might have changed:
|
||||
////make sure the internal child collision algorithm caches are still valid
|
||||
if (compoundShape->getUpdateRevision() != m_compoundShapeRevision)
|
||||
{
|
||||
///clear and update all
|
||||
removeChildAlgorithms();
|
||||
|
||||
preallocateChildAlgorithms(body0,body1);
|
||||
}
|
||||
|
||||
|
||||
btDbvt* tree = compoundShape->getDynamicAabbTree();
|
||||
//use a dynamic aabb tree to cull potential child-overlaps
|
||||
btCompoundLeafCallback callback(colObj,otherObj,m_dispatcher,dispatchInfo,resultOut,&m_childCollisionAlgorithms[0],m_sharedManifold);
|
||||
|
||||
///we need to refresh all contact manifolds
|
||||
///note that we should actually recursively traverse all children, btCompoundShape can nested more then 1 level deep
|
||||
///so we should add a 'refreshManifolds' in the btCollisionAlgorithm
|
||||
{
|
||||
int i;
|
||||
btManifoldArray manifoldArray;
|
||||
for (i=0;i<m_childCollisionAlgorithms.size();i++)
|
||||
{
|
||||
if (m_childCollisionAlgorithms[i])
|
||||
{
|
||||
m_childCollisionAlgorithms[i]->getAllContactManifolds(manifoldArray);
|
||||
for (int m=0;m<manifoldArray.size();m++)
|
||||
{
|
||||
if (manifoldArray[m]->getNumContacts())
|
||||
{
|
||||
resultOut->setPersistentManifold(manifoldArray[m]);
|
||||
resultOut->refreshContactPoints();
|
||||
resultOut->setPersistentManifold(0);//??necessary?
|
||||
}
|
||||
}
|
||||
manifoldArray.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tree)
|
||||
{
|
||||
@ -242,7 +296,7 @@ btScalar btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject*
|
||||
btCollisionObject* colObj = m_isSwapped? body1 : body0;
|
||||
btCollisionObject* otherObj = m_isSwapped? body0 : body1;
|
||||
|
||||
assert (colObj->getCollisionShape()->isCompound());
|
||||
btAssert (colObj->getCollisionShape()->isCompound());
|
||||
|
||||
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
|
||||
|
||||
@ -285,3 +339,4 @@ btScalar btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject*
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -16,7 +16,7 @@ subject to the following restrictions:
|
||||
#ifndef COMPOUND_COLLISION_ALGORITHM_H
|
||||
#define COMPOUND_COLLISION_ALGORITHM_H
|
||||
|
||||
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
|
||||
#include "btActivatingCollisionAlgorithm.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
|
||||
|
||||
@ -26,16 +26,23 @@ class btDispatcher;
|
||||
#include "btCollisionCreateFunc.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
class btDispatcher;
|
||||
class btCollisionObject;
|
||||
|
||||
/// btCompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision shapes
|
||||
class btCompoundCollisionAlgorithm : public btCollisionAlgorithm
|
||||
class btCompoundCollisionAlgorithm : public btActivatingCollisionAlgorithm
|
||||
{
|
||||
btAlignedObjectArray<btCollisionAlgorithm*> m_childCollisionAlgorithms;
|
||||
bool m_isSwapped;
|
||||
|
||||
class btPersistentManifold* m_sharedManifold;
|
||||
bool m_ownsManifold;
|
||||
|
||||
int m_compoundShapeRevision;//to keep track of changes, so that childAlgorithm array can be updated
|
||||
|
||||
void removeChildAlgorithms();
|
||||
|
||||
void preallocateChildAlgorithms(btCollisionObject* body0,btCollisionObject* body1);
|
||||
|
||||
public:
|
||||
|
||||
btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
|
||||
|
6
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
vendored
6
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
vendored
@ -27,7 +27,7 @@ subject to the following restrictions:
|
||||
#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
|
||||
|
||||
btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
|
||||
: btCollisionAlgorithm(ci),
|
||||
: btActivatingCollisionAlgorithm(ci,body0,body1),
|
||||
m_isSwapped(isSwapped),
|
||||
m_btConvexTriangleCallback(ci.m_dispatcher1,body0,body1,isSwapped)
|
||||
{
|
||||
@ -72,7 +72,7 @@ btConvexTriangleCallback::~btConvexTriangleCallback()
|
||||
void btConvexTriangleCallback::clearCache()
|
||||
{
|
||||
m_dispatcher->clearManifold(m_manifoldPtr);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -93,7 +93,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
|
||||
|
||||
|
||||
///debug drawing of the overlapping triangles
|
||||
if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && m_dispatchInfoPtr->m_debugDraw->getDebugMode() > 0)
|
||||
if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe ))
|
||||
{
|
||||
btVector3 color(255,255,0);
|
||||
btTransform& tr = ob->getWorldTransform();
|
||||
|
@ -16,7 +16,7 @@ subject to the following restrictions:
|
||||
#ifndef CONVEX_CONCAVE_COLLISION_ALGORITHM_H
|
||||
#define CONVEX_CONCAVE_COLLISION_ALGORITHM_H
|
||||
|
||||
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
|
||||
#include "btActivatingCollisionAlgorithm.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
|
||||
#include "BulletCollision/CollisionShapes/btTriangleCallback.h"
|
||||
@ -34,8 +34,8 @@ class btConvexTriangleCallback : public btTriangleCallback
|
||||
btVector3 m_aabbMin;
|
||||
btVector3 m_aabbMax ;
|
||||
|
||||
btManifoldResult* m_resultOut;
|
||||
|
||||
btManifoldResult* m_resultOut;
|
||||
btDispatcher* m_dispatcher;
|
||||
const btDispatcherInfo* m_dispatchInfoPtr;
|
||||
btScalar m_collisionMarginTriangle;
|
||||
@ -70,7 +70,7 @@ int m_triangleCount;
|
||||
|
||||
|
||||
/// btConvexConcaveCollisionAlgorithm supports collision between convex shapes and (concave) trianges meshes.
|
||||
class btConvexConcaveCollisionAlgorithm : public btCollisionAlgorithm
|
||||
class btConvexConcaveCollisionAlgorithm : public btActivatingCollisionAlgorithm
|
||||
{
|
||||
|
||||
bool m_isSwapped;
|
||||
@ -78,6 +78,7 @@ class btConvexConcaveCollisionAlgorithm : public btCollisionAlgorithm
|
||||
btConvexTriangleCallback m_btConvexTriangleCallback;
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
|
||||
|
@ -38,7 +38,7 @@ subject to the following restrictions:
|
||||
|
||||
#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
|
||||
|
||||
#include "BulletCollision/NarrowPhaseCollision/btGjkEpa.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
|
||||
|
||||
|
||||
@ -51,6 +51,8 @@ subject to the following restrictions:
|
||||
|
||||
btConvexConvexAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
|
||||
{
|
||||
m_numPerturbationIterations = 0;
|
||||
m_minimumPointsPerturbationThreshold = 3;
|
||||
m_simplexSolver = simplexSolver;
|
||||
m_pdSolver = pdSolver;
|
||||
}
|
||||
@ -59,17 +61,22 @@ btConvexConvexAlgorithm::CreateFunc::~CreateFunc()
|
||||
{
|
||||
}
|
||||
|
||||
btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
|
||||
: btCollisionAlgorithm(ci),
|
||||
m_gjkPairDetector(0,0,simplexSolver,pdSolver),
|
||||
btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold)
|
||||
: btActivatingCollisionAlgorithm(ci,body0,body1),
|
||||
m_simplexSolver(simplexSolver),
|
||||
m_pdSolver(pdSolver),
|
||||
m_ownManifold (false),
|
||||
m_manifoldPtr(mf),
|
||||
m_lowLevelOfDetail(false)
|
||||
m_lowLevelOfDetail(false),
|
||||
#ifdef USE_SEPDISTANCE_UTIL2
|
||||
,m_sepDistance((static_cast<btConvexShape*>(body0->getCollisionShape()))->getAngularMotionDisc(),
|
||||
(static_cast<btConvexShape*>(body1->getCollisionShape()))->getAngularMotionDisc()),
|
||||
#endif
|
||||
m_numPerturbationIterations(numPerturbationIterations),
|
||||
m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold)
|
||||
{
|
||||
(void)body0;
|
||||
(void)body1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -90,8 +97,63 @@ void btConvexConvexAlgorithm ::setLowLevelOfDetail(bool useLowLevel)
|
||||
}
|
||||
|
||||
|
||||
struct btPerturbedContactResult : public btManifoldResult
|
||||
{
|
||||
btManifoldResult* m_originalManifoldResult;
|
||||
btTransform m_transformA;
|
||||
btTransform m_transformB;
|
||||
btTransform m_unPerturbedTransform;
|
||||
bool m_perturbA;
|
||||
btIDebugDraw* m_debugDrawer;
|
||||
|
||||
|
||||
btPerturbedContactResult(btManifoldResult* originalResult,const btTransform& transformA,const btTransform& transformB,const btTransform& unPerturbedTransform,bool perturbA,btIDebugDraw* debugDrawer)
|
||||
:m_originalManifoldResult(originalResult),
|
||||
m_transformA(transformA),
|
||||
m_transformB(transformB),
|
||||
m_perturbA(perturbA),
|
||||
m_unPerturbedTransform(unPerturbedTransform),
|
||||
m_debugDrawer(debugDrawer)
|
||||
{
|
||||
}
|
||||
virtual ~ btPerturbedContactResult()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar orgDepth)
|
||||
{
|
||||
btVector3 endPt,startPt;
|
||||
btScalar newDepth;
|
||||
btVector3 newNormal;
|
||||
|
||||
if (m_perturbA)
|
||||
{
|
||||
btVector3 endPtOrg = pointInWorld + normalOnBInWorld*orgDepth;
|
||||
endPt = (m_unPerturbedTransform*m_transformA.inverse())(endPtOrg);
|
||||
newDepth = (endPt - pointInWorld).dot(normalOnBInWorld);
|
||||
startPt = endPt+normalOnBInWorld*newDepth;
|
||||
} else
|
||||
{
|
||||
endPt = pointInWorld + normalOnBInWorld*orgDepth;
|
||||
startPt = (m_unPerturbedTransform*m_transformB.inverse())(pointInWorld);
|
||||
newDepth = (endPt - startPt).dot(normalOnBInWorld);
|
||||
|
||||
}
|
||||
|
||||
//#define DEBUG_CONTACTS 1
|
||||
#ifdef DEBUG_CONTACTS
|
||||
m_debugDrawer->drawLine(startPt,endPt,btVector3(1,0,0));
|
||||
m_debugDrawer->drawSphere(startPt,0.05,btVector3(0,1,0));
|
||||
m_debugDrawer->drawSphere(endPt,0.05,btVector3(0,0,1));
|
||||
#endif //DEBUG_CONTACTS
|
||||
|
||||
|
||||
m_originalManifoldResult->addContactPoint(normalOnBInWorld,startPt,newDepth);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
extern btScalar gContactBreakingThreshold;
|
||||
|
||||
//
|
||||
// Convex-Convex collision algorithm
|
||||
@ -107,39 +169,125 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
|
||||
}
|
||||
resultOut->setPersistentManifold(m_manifoldPtr);
|
||||
|
||||
#ifdef USE_BT_GJKEPA
|
||||
btConvexShape* shape0(static_cast<btConvexShape*>(body0->getCollisionShape()));
|
||||
btConvexShape* shape1(static_cast<btConvexShape*>(body1->getCollisionShape()));
|
||||
const btScalar radialmargin(0/*shape0->getMargin()+shape1->getMargin()*/);
|
||||
btGjkEpaSolver::sResults results;
|
||||
if(btGjkEpaSolver::Collide( shape0,body0->getWorldTransform(),
|
||||
shape1,body1->getWorldTransform(),
|
||||
radialmargin,results))
|
||||
{
|
||||
dispatchInfo.m_debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0));
|
||||
resultOut->addContactPoint(results.normal,results.witnesses[1],-results.depth);
|
||||
}
|
||||
#else
|
||||
//comment-out next line to test multi-contact generation
|
||||
//resultOut->getPersistentManifold()->clearManifold();
|
||||
|
||||
|
||||
btConvexShape* min0 = static_cast<btConvexShape*>(body0->getCollisionShape());
|
||||
btConvexShape* min1 = static_cast<btConvexShape*>(body1->getCollisionShape());
|
||||
|
||||
#ifdef USE_SEPDISTANCE_UTIL2
|
||||
m_sepDistance.updateSeparatingDistance(body0->getWorldTransform(),body1->getWorldTransform());
|
||||
if (!dispatchInfo.m_useConvexConservativeDistanceUtil || m_sepDistance.getConservativeSeparatingDistance()<=0.f)
|
||||
#endif //USE_SEPDISTANCE_UTIL2
|
||||
|
||||
{
|
||||
|
||||
|
||||
btGjkPairDetector::ClosestPointInput input;
|
||||
|
||||
btGjkPairDetector gjkPairDetector(min0,min1,m_simplexSolver,m_pdSolver);
|
||||
//TODO: if (dispatchInfo.m_useContinuous)
|
||||
m_gjkPairDetector.setMinkowskiA(min0);
|
||||
m_gjkPairDetector.setMinkowskiB(min1);
|
||||
input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
|
||||
input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
|
||||
input.m_stackAlloc = dispatchInfo.m_stackAllocator;
|
||||
gjkPairDetector.setMinkowskiA(min0);
|
||||
gjkPairDetector.setMinkowskiB(min1);
|
||||
|
||||
// input.m_maximumDistanceSquared = btScalar(1e30);
|
||||
|
||||
#ifdef USE_SEPDISTANCE_UTIL2
|
||||
if (dispatchInfo.m_useConvexConservativeDistanceUtil)
|
||||
{
|
||||
input.m_maximumDistanceSquared = 1e30f;
|
||||
} else
|
||||
#endif //USE_SEPDISTANCE_UTIL2
|
||||
{
|
||||
input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
|
||||
input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
|
||||
}
|
||||
|
||||
input.m_stackAlloc = dispatchInfo.m_stackAllocator;
|
||||
input.m_transformA = body0->getWorldTransform();
|
||||
input.m_transformB = body1->getWorldTransform();
|
||||
|
||||
gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
|
||||
btScalar sepDist = gjkPairDetector.getCachedSeparatingDistance()+dispatchInfo.m_convexConservativeDistanceThreshold;
|
||||
|
||||
//now perturbe directions to get multiple contact points
|
||||
btVector3 v0,v1;
|
||||
btVector3 sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis().normalized();
|
||||
btPlaneSpace1(sepNormalWorldSpace,v0,v1);
|
||||
//now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects
|
||||
|
||||
m_gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
|
||||
//perform perturbation when more then 'm_minimumPointsPerturbationThreshold' points
|
||||
if (resultOut->getPersistentManifold()->getNumContacts() < m_minimumPointsPerturbationThreshold)
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
bool perturbeA = true;
|
||||
const btScalar angleLimit = 0.125f * SIMD_PI;
|
||||
btScalar perturbeAngle;
|
||||
btScalar radiusA = min0->getAngularMotionDisc();
|
||||
btScalar radiusB = min1->getAngularMotionDisc();
|
||||
if (radiusA < radiusB)
|
||||
{
|
||||
perturbeAngle = gContactBreakingThreshold /radiusA;
|
||||
perturbeA = true;
|
||||
} else
|
||||
{
|
||||
perturbeAngle = gContactBreakingThreshold / radiusB;
|
||||
perturbeA = false;
|
||||
}
|
||||
if ( perturbeAngle > angleLimit )
|
||||
perturbeAngle = angleLimit;
|
||||
|
||||
btTransform unPerturbedTransform;
|
||||
if (perturbeA)
|
||||
{
|
||||
unPerturbedTransform = input.m_transformA;
|
||||
} else
|
||||
{
|
||||
unPerturbedTransform = input.m_transformB;
|
||||
}
|
||||
|
||||
for ( i=0;i<m_numPerturbationIterations;i++)
|
||||
{
|
||||
btQuaternion perturbeRot(v0,perturbeAngle);
|
||||
btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations));
|
||||
btQuaternion rotq(sepNormalWorldSpace,iterationAngle);
|
||||
|
||||
|
||||
if (perturbeA)
|
||||
{
|
||||
input.m_transformA.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body0->getWorldTransform().getBasis());
|
||||
input.m_transformB = body1->getWorldTransform();
|
||||
#ifdef DEBUG_CONTACTS
|
||||
dispatchInfo.m_debugDraw->drawTransform(input.m_transformA,10.0);
|
||||
#endif //DEBUG_CONTACTS
|
||||
} else
|
||||
{
|
||||
input.m_transformA = body0->getWorldTransform();
|
||||
input.m_transformB.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body1->getWorldTransform().getBasis());
|
||||
#ifdef DEBUG_CONTACTS
|
||||
dispatchInfo.m_debugDraw->drawTransform(input.m_transformB,10.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
btPerturbedContactResult perturbedResultOut(resultOut,input.m_transformA,input.m_transformB,unPerturbedTransform,perturbeA,dispatchInfo.m_debugDraw);
|
||||
gjkPairDetector.getClosestPoints(input,perturbedResultOut,dispatchInfo.m_debugDraw);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef USE_SEPDISTANCE_UTIL2
|
||||
if (dispatchInfo.m_useConvexConservativeDistanceUtil)
|
||||
{
|
||||
m_sepDistance.initSeparatingDistance(gjkPairDetector.getCachedSeparatingAxis(),sepDist,body0->getWorldTransform(),body1->getWorldTransform());
|
||||
}
|
||||
#endif //USE_SEPDISTANCE_UTIL2
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (m_ownManifold)
|
||||
{
|
||||
|
@ -16,30 +16,50 @@ subject to the following restrictions:
|
||||
#ifndef CONVEX_CONVEX_ALGORITHM_H
|
||||
#define CONVEX_CONVEX_ALGORITHM_H
|
||||
|
||||
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
|
||||
#include "btActivatingCollisionAlgorithm.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"
|
||||
#include "LinearMath/btTransformUtil.h" //for btConvexSeparatingDistanceUtil
|
||||
|
||||
class btConvexPenetrationDepthSolver;
|
||||
|
||||
///ConvexConvexAlgorithm collision algorithm implements time of impact, convex closest points and penetration depth calculations.
|
||||
class btConvexConvexAlgorithm : public btCollisionAlgorithm
|
||||
{
|
||||
btGjkPairDetector m_gjkPairDetector;
|
||||
public:
|
||||
///Enabling USE_SEPDISTANCE_UTIL2 requires 100% reliable distance computation. However, when using large size ratios GJK can be imprecise
|
||||
///so the distance is not conservative. In that case, enabling this USE_SEPDISTANCE_UTIL2 would result in failing/missing collisions.
|
||||
///Either improve GJK for large size ratios (testing a 100 units versus a 0.1 unit object) or only enable the util
|
||||
///for certain pairs that have a small size ratio
|
||||
///#define USE_SEPDISTANCE_UTIL2 1
|
||||
|
||||
///The convexConvexAlgorithm collision algorithm implements time of impact, convex closest points and penetration depth calculations between two convex objects.
|
||||
///Multiple contact points are calculated by perturbing the orientation of the smallest object orthogonal to the separating normal.
|
||||
///This idea was described by Gino van den Bergen in this forum topic http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=4&t=288&p=888#p888
|
||||
class btConvexConvexAlgorithm : public btActivatingCollisionAlgorithm
|
||||
{
|
||||
#ifdef USE_SEPDISTANCE_UTIL2
|
||||
btConvexSeparatingDistanceUtil m_sepDistance;
|
||||
#endif
|
||||
btSimplexSolverInterface* m_simplexSolver;
|
||||
btConvexPenetrationDepthSolver* m_pdSolver;
|
||||
|
||||
|
||||
bool m_ownManifold;
|
||||
btPersistentManifold* m_manifoldPtr;
|
||||
bool m_lowLevelOfDetail;
|
||||
|
||||
int m_numPerturbationIterations;
|
||||
int m_minimumPointsPerturbationThreshold;
|
||||
|
||||
|
||||
///cache separating vector to speedup collision detection
|
||||
|
||||
|
||||
public:
|
||||
|
||||
btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver);
|
||||
btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold);
|
||||
|
||||
|
||||
virtual ~btConvexConvexAlgorithm();
|
||||
|
||||
@ -65,9 +85,12 @@ public:
|
||||
|
||||
struct CreateFunc :public btCollisionAlgorithmCreateFunc
|
||||
{
|
||||
|
||||
btConvexPenetrationDepthSolver* m_pdSolver;
|
||||
btSimplexSolverInterface* m_simplexSolver;
|
||||
|
||||
int m_numPerturbationIterations;
|
||||
int m_minimumPointsPerturbationThreshold;
|
||||
|
||||
CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver);
|
||||
|
||||
virtual ~CreateFunc();
|
||||
@ -75,7 +98,7 @@ public:
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
|
||||
{
|
||||
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConvexAlgorithm));
|
||||
return new(mem) btConvexConvexAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver);
|
||||
return new(mem) btConvexConvexAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
|
||||
}
|
||||
};
|
||||
|
||||
|
85
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
vendored
85
extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
vendored
@ -4,8 +4,8 @@ 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,
|
||||
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.
|
||||
@ -22,15 +22,17 @@ subject to the following restrictions:
|
||||
|
||||
//#include <stdio.h>
|
||||
|
||||
btConvexPlaneCollisionAlgorithm::btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped)
|
||||
btConvexPlaneCollisionAlgorithm::btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped, int numPerturbationIterations,int minimumPointsPerturbationThreshold)
|
||||
: btCollisionAlgorithm(ci),
|
||||
m_ownManifold(false),
|
||||
m_manifoldPtr(mf),
|
||||
m_isSwapped(isSwapped)
|
||||
m_isSwapped(isSwapped),
|
||||
m_numPerturbationIterations(numPerturbationIterations),
|
||||
m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold)
|
||||
{
|
||||
btCollisionObject* convexObj = m_isSwapped? col1 : col0;
|
||||
btCollisionObject* planeObj = m_isSwapped? col0 : col1;
|
||||
|
||||
|
||||
if (!m_manifoldPtr && m_dispatcher->needsCollision(convexObj,planeObj))
|
||||
{
|
||||
m_manifoldPtr = m_dispatcher->getNewManifold(convexObj,planeObj);
|
||||
@ -48,30 +50,28 @@ btConvexPlaneCollisionAlgorithm::~btConvexPlaneCollisionAlgorithm()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void btConvexPlaneCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||
void btConvexPlaneCollisionAlgorithm::collideSingleContact (const btQuaternion& perturbeRot, btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||
{
|
||||
(void)dispatchInfo;
|
||||
(void)resultOut;
|
||||
if (!m_manifoldPtr)
|
||||
return;
|
||||
|
||||
btCollisionObject* convexObj = m_isSwapped? body1 : body0;
|
||||
btCollisionObject* convexObj = m_isSwapped? body1 : body0;
|
||||
btCollisionObject* planeObj = m_isSwapped? body0: body1;
|
||||
|
||||
btConvexShape* convexShape = (btConvexShape*) convexObj->getCollisionShape();
|
||||
btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObj->getCollisionShape();
|
||||
|
||||
bool hasCollision = false;
|
||||
bool hasCollision = false;
|
||||
const btVector3& planeNormal = planeShape->getPlaneNormal();
|
||||
const btScalar& planeConstant = planeShape->getPlaneConstant();
|
||||
btTransform planeInConvex;
|
||||
planeInConvex= convexObj->getWorldTransform().inverse() * planeObj->getWorldTransform();
|
||||
|
||||
btTransform convexWorldTransform = convexObj->getWorldTransform();
|
||||
btTransform convexInPlaneTrans;
|
||||
convexInPlaneTrans= planeObj->getWorldTransform().inverse() * convexObj->getWorldTransform();
|
||||
|
||||
convexInPlaneTrans= planeObj->getWorldTransform().inverse() * convexWorldTransform;
|
||||
//now perturbe the convex-world transform
|
||||
convexWorldTransform.getBasis()*=btMatrix3x3(perturbeRot);
|
||||
btTransform planeInConvex;
|
||||
planeInConvex= convexWorldTransform.inverse() * planeObj->getWorldTransform();
|
||||
|
||||
btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal);
|
||||
|
||||
btVector3 vtxInPlane = convexInPlaneTrans(vtx);
|
||||
btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant);
|
||||
|
||||
@ -87,6 +87,53 @@ void btConvexPlaneCollisionAlgorithm::processCollision (btCollisionObject* body0
|
||||
btVector3 pOnB = vtxInPlaneWorld;
|
||||
resultOut->addContactPoint(normalOnSurfaceB,pOnB,distance);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void btConvexPlaneCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||
{
|
||||
(void)dispatchInfo;
|
||||
if (!m_manifoldPtr)
|
||||
return;
|
||||
|
||||
btCollisionObject* convexObj = m_isSwapped? body1 : body0;
|
||||
btCollisionObject* planeObj = m_isSwapped? body0: body1;
|
||||
|
||||
btConvexShape* convexShape = (btConvexShape*) convexObj->getCollisionShape();
|
||||
btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObj->getCollisionShape();
|
||||
|
||||
bool hasCollision = false;
|
||||
const btVector3& planeNormal = planeShape->getPlaneNormal();
|
||||
const btScalar& planeConstant = planeShape->getPlaneConstant();
|
||||
|
||||
//first perform a collision query with the non-perturbated collision objects
|
||||
{
|
||||
btQuaternion rotq(0,0,0,1);
|
||||
collideSingleContact(rotq,body0,body1,dispatchInfo,resultOut);
|
||||
}
|
||||
|
||||
if (resultOut->getPersistentManifold()->getNumContacts()<m_minimumPointsPerturbationThreshold)
|
||||
{
|
||||
btVector3 v0,v1;
|
||||
btPlaneSpace1(planeNormal,v0,v1);
|
||||
//now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects
|
||||
|
||||
const btScalar angleLimit = 0.125f * SIMD_PI;
|
||||
btScalar perturbeAngle;
|
||||
btScalar radius = convexShape->getAngularMotionDisc();
|
||||
perturbeAngle = gContactBreakingThreshold / radius;
|
||||
if ( perturbeAngle > angleLimit )
|
||||
perturbeAngle = angleLimit;
|
||||
|
||||
btQuaternion perturbeRot(v0,perturbeAngle);
|
||||
for (int i=0;i<m_numPerturbationIterations;i++)
|
||||
{
|
||||
btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations));
|
||||
btQuaternion rotq(planeNormal,iterationAngle);
|
||||
collideSingleContact(rotq.inverse()*perturbeRot*rotq,body0,body1,dispatchInfo,resultOut);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_ownManifold)
|
||||
{
|
||||
if (m_manifoldPtr->getNumContacts())
|
||||
|
@ -4,8 +4,8 @@ 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,
|
||||
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.
|
||||
@ -28,18 +28,22 @@ class btPersistentManifold;
|
||||
/// Other features are frame-coherency (persistent data) and collision response.
|
||||
class btConvexPlaneCollisionAlgorithm : public btCollisionAlgorithm
|
||||
{
|
||||
bool m_ownManifold;
|
||||
bool m_ownManifold;
|
||||
btPersistentManifold* m_manifoldPtr;
|
||||
bool m_isSwapped;
|
||||
|
||||
bool m_isSwapped;
|
||||
int m_numPerturbationIterations;
|
||||
int m_minimumPointsPerturbationThreshold;
|
||||
|
||||
public:
|
||||
|
||||
btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped);
|
||||
btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped, int numPerturbationIterations,int minimumPointsPerturbationThreshold);
|
||||
|
||||
virtual ~btConvexPlaneCollisionAlgorithm();
|
||||
|
||||
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
void collideSingleContact (const btQuaternion& perturbeRot, btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
|
||||
@ -52,15 +56,24 @@ public:
|
||||
|
||||
struct CreateFunc :public btCollisionAlgorithmCreateFunc
|
||||
{
|
||||
int m_numPerturbationIterations;
|
||||
int m_minimumPointsPerturbationThreshold;
|
||||
|
||||
CreateFunc()
|
||||
: m_numPerturbationIterations(3),
|
||||
m_minimumPointsPerturbationThreshold(3)
|
||||
{
|
||||
}
|
||||
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
|
||||
{
|
||||
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexPlaneCollisionAlgorithm));
|
||||
if (!m_swapped)
|
||||
{
|
||||
return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,false);
|
||||
return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,false,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
|
||||
} else
|
||||
{
|
||||
return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,true);
|
||||
return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,true,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
12
extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp
vendored
12
extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp
vendored
@ -100,11 +100,10 @@ btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(const btDefault
|
||||
int maxSize = sizeof(btConvexConvexAlgorithm);
|
||||
int maxSize2 = sizeof(btConvexConcaveCollisionAlgorithm);
|
||||
int maxSize3 = sizeof(btCompoundCollisionAlgorithm);
|
||||
int maxSize4 = sizeof(btEmptyAlgorithm);
|
||||
|
||||
int sl = sizeof(btConvexSeparatingDistanceUtil);
|
||||
sl = sizeof(btGjkPairDetector);
|
||||
int collisionAlgorithmMaxElementSize = btMax(maxSize,maxSize2);
|
||||
collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3);
|
||||
collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize4);
|
||||
|
||||
if (constructionInfo.m_stackAlloc)
|
||||
{
|
||||
@ -289,3 +288,10 @@ btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlg
|
||||
//failed to find an algorithm
|
||||
return m_emptyCreateFunc;
|
||||
}
|
||||
|
||||
void btDefaultCollisionConfiguration::setConvexConvexMultipointIterations(int numPerturbationIterations, int minimumPointsPerturbationThreshold)
|
||||
{
|
||||
btConvexConvexAlgorithm::CreateFunc* convexConvex = (btConvexConvexAlgorithm::CreateFunc*) m_convexConvexCreateFunc;
|
||||
convexConvex->m_numPerturbationIterations = numPerturbationIterations;
|
||||
convexConvex->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
|
||||
}
|
||||
|
@ -33,9 +33,9 @@ struct btDefaultCollisionConstructionInfo
|
||||
:m_stackAlloc(0),
|
||||
m_persistentManifoldPool(0),
|
||||
m_collisionAlgorithmPool(0),
|
||||
m_defaultMaxPersistentManifoldPoolSize(65535),
|
||||
m_defaultMaxCollisionAlgorithmPoolSize(65535),
|
||||
m_defaultStackAllocatorSize(5*1024*1024)
|
||||
m_defaultMaxPersistentManifoldPoolSize(4096),
|
||||
m_defaultMaxCollisionAlgorithmPoolSize(4096),
|
||||
m_defaultStackAllocatorSize(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
@ -44,7 +44,7 @@ struct btDefaultCollisionConstructionInfo
|
||||
|
||||
///btCollisionConfiguration allows to configure Bullet collision detection
|
||||
///stack allocator, pool memory allocators
|
||||
///todo: describe the meaning
|
||||
///@todo: describe the meaning
|
||||
class btDefaultCollisionConfiguration : public btCollisionConfiguration
|
||||
{
|
||||
|
||||
@ -111,6 +111,14 @@ public:
|
||||
|
||||
virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1);
|
||||
|
||||
///Use this method to allow to generate multiple contact points between at once, between two objects using the generic convex-convex algorithm.
|
||||
///By default, this feature is disabled for best performance.
|
||||
///@param numPerturbationIterations controls the number of collision queries. Set it to zero to disable the feature.
|
||||
///@param minimumPointsPerturbationThreshold is the minimum number of points in the contact cache, above which the feature is disabled
|
||||
///3 is a good value for both params, if you want to enable the feature. This is because the default contact cache contains a maximum of 4 points, and one collision query at the unperturbed orientation is performed first.
|
||||
///See Bullet/Demos/CollisionDemo for an example how this feature gathers multiple points.
|
||||
///@todo we could add a per-object setting of those parameters, for level-of-detail collision detection.
|
||||
void setConvexConvexMultipointIterations(int numPerturbationIterations=3, int minimumPointsPerturbationThreshold = 3);
|
||||
|
||||
};
|
||||
|
||||
|
171
extern/bullet2/src/BulletCollision/CollisionDispatch/btGhostObject.cpp
vendored
Normal file
171
extern/bullet2/src/BulletCollision/CollisionDispatch/btGhostObject.cpp
vendored
Normal file
@ -0,0 +1,171 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
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 "btGhostObject.h"
|
||||
#include "btCollisionWorld.h"
|
||||
#include "BulletCollision/CollisionShapes/btConvexShape.h"
|
||||
#include "LinearMath/btAabbUtil2.h"
|
||||
|
||||
btGhostObject::btGhostObject()
|
||||
{
|
||||
m_internalType = CO_GHOST_OBJECT;
|
||||
}
|
||||
|
||||
btGhostObject::~btGhostObject()
|
||||
{
|
||||
///btGhostObject should have been removed from the world, so no overlapping objects
|
||||
btAssert(!m_overlappingObjects.size());
|
||||
}
|
||||
|
||||
|
||||
void btGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btBroadphaseProxy* thisProxy)
|
||||
{
|
||||
btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
|
||||
btAssert(otherObject);
|
||||
///if this linearSearch becomes too slow (too many overlapping objects) we should add a more appropriate data structure
|
||||
int index = m_overlappingObjects.findLinearSearch(otherObject);
|
||||
if (index==m_overlappingObjects.size())
|
||||
{
|
||||
//not found
|
||||
m_overlappingObjects.push_back(otherObject);
|
||||
}
|
||||
}
|
||||
|
||||
void btGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy)
|
||||
{
|
||||
btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
|
||||
btAssert(otherObject);
|
||||
int index = m_overlappingObjects.findLinearSearch(otherObject);
|
||||
if (index<m_overlappingObjects.size())
|
||||
{
|
||||
m_overlappingObjects[index] = m_overlappingObjects[m_overlappingObjects.size()-1];
|
||||
m_overlappingObjects.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
btPairCachingGhostObject::btPairCachingGhostObject()
|
||||
{
|
||||
m_hashPairCache = new (btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache();
|
||||
}
|
||||
|
||||
btPairCachingGhostObject::~btPairCachingGhostObject()
|
||||
{
|
||||
m_hashPairCache->~btHashedOverlappingPairCache();
|
||||
btAlignedFree( m_hashPairCache );
|
||||
}
|
||||
|
||||
void btPairCachingGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btBroadphaseProxy* thisProxy)
|
||||
{
|
||||
btBroadphaseProxy*actualThisProxy = thisProxy ? thisProxy : getBroadphaseHandle();
|
||||
btAssert(actualThisProxy);
|
||||
|
||||
btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
|
||||
btAssert(otherObject);
|
||||
int index = m_overlappingObjects.findLinearSearch(otherObject);
|
||||
if (index==m_overlappingObjects.size())
|
||||
{
|
||||
m_overlappingObjects.push_back(otherObject);
|
||||
m_hashPairCache->addOverlappingPair(actualThisProxy,otherProxy);
|
||||
}
|
||||
}
|
||||
|
||||
void btPairCachingGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy1)
|
||||
{
|
||||
btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
|
||||
btBroadphaseProxy* actualThisProxy = thisProxy1 ? thisProxy1 : getBroadphaseHandle();
|
||||
btAssert(actualThisProxy);
|
||||
|
||||
btAssert(otherObject);
|
||||
int index = m_overlappingObjects.findLinearSearch(otherObject);
|
||||
if (index<m_overlappingObjects.size())
|
||||
{
|
||||
m_overlappingObjects[index] = m_overlappingObjects[m_overlappingObjects.size()-1];
|
||||
m_overlappingObjects.pop_back();
|
||||
m_hashPairCache->removeOverlappingPair(actualThisProxy,otherProxy,dispatcher);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void btGhostObject::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, btCollisionWorld::ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const
|
||||
{
|
||||
btTransform convexFromTrans,convexToTrans;
|
||||
convexFromTrans = convexFromWorld;
|
||||
convexToTrans = convexToWorld;
|
||||
btVector3 castShapeAabbMin, castShapeAabbMax;
|
||||
/* Compute AABB that encompasses angular movement */
|
||||
{
|
||||
btVector3 linVel, angVel;
|
||||
btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0, linVel, angVel);
|
||||
btTransform R;
|
||||
R.setIdentity ();
|
||||
R.setRotation (convexFromTrans.getRotation());
|
||||
castShape->calculateTemporalAabb (R, linVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
|
||||
}
|
||||
|
||||
/// go over all objects, and if the ray intersects their aabb + cast shape aabb,
|
||||
// do a ray-shape query using convexCaster (CCD)
|
||||
int i;
|
||||
for (i=0;i<m_overlappingObjects.size();i++)
|
||||
{
|
||||
btCollisionObject* collisionObject= m_overlappingObjects[i];
|
||||
//only perform raycast if filterMask matches
|
||||
if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
|
||||
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
|
||||
btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
|
||||
collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
|
||||
AabbExpand (collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax);
|
||||
btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing
|
||||
btVector3 hitNormal;
|
||||
if (btRayAabb(convexFromWorld.getOrigin(),convexToWorld.getOrigin(),collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
|
||||
{
|
||||
btCollisionWorld::objectQuerySingle(castShape, convexFromTrans,convexToTrans,
|
||||
collisionObject,
|
||||
collisionObject->getCollisionShape(),
|
||||
collisionObject->getWorldTransform(),
|
||||
resultCallback,
|
||||
allowedCcdPenetration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void btGhostObject::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const
|
||||
{
|
||||
btTransform rayFromTrans;
|
||||
rayFromTrans.setIdentity();
|
||||
rayFromTrans.setOrigin(rayFromWorld);
|
||||
btTransform rayToTrans;
|
||||
rayToTrans.setIdentity();
|
||||
rayToTrans.setOrigin(rayToWorld);
|
||||
|
||||
|
||||
int i;
|
||||
for (i=0;i<m_overlappingObjects.size();i++)
|
||||
{
|
||||
btCollisionObject* collisionObject= m_overlappingObjects[i];
|
||||
//only perform raycast if filterMask matches
|
||||
if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
|
||||
{
|
||||
btCollisionWorld::rayTestSingle(rayFromTrans,rayToTrans,
|
||||
collisionObject,
|
||||
collisionObject->getCollisionShape(),
|
||||
collisionObject->getWorldTransform(),
|
||||
resultCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
174
extern/bullet2/src/BulletCollision/CollisionDispatch/btGhostObject.h
vendored
Normal file
174
extern/bullet2/src/BulletCollision/CollisionDispatch/btGhostObject.h
vendored
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
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_GHOST_OBJECT_H
|
||||
#define BT_GHOST_OBJECT_H
|
||||
|
||||
|
||||
#include "btCollisionObject.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h"
|
||||
#include "LinearMath/btAlignedAllocator.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
|
||||
#include "btCollisionWorld.h"
|
||||
|
||||
class btConvexShape;
|
||||
|
||||
class btDispatcher;
|
||||
|
||||
///The btGhostObject can keep track of all objects that are overlapping
|
||||
///By default, this overlap is based on the AABB
|
||||
///This is useful for creating a character controller, collision sensors/triggers, explosions etc.
|
||||
///We plan on adding rayTest and other queries for the btGhostObject
|
||||
ATTRIBUTE_ALIGNED16(class) btGhostObject : public btCollisionObject
|
||||
{
|
||||
protected:
|
||||
|
||||
btAlignedObjectArray<btCollisionObject*> m_overlappingObjects;
|
||||
|
||||
public:
|
||||
|
||||
btGhostObject();
|
||||
|
||||
virtual ~btGhostObject();
|
||||
|
||||
void convexSweepTest(const class btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, btCollisionWorld::ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration = 0.f) const;
|
||||
|
||||
void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const;
|
||||
|
||||
///this method is mainly for expert/internal use only.
|
||||
virtual void addOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btBroadphaseProxy* thisProxy=0);
|
||||
///this method is mainly for expert/internal use only.
|
||||
virtual void removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy=0);
|
||||
|
||||
int getNumOverlappingObjects() const
|
||||
{
|
||||
return m_overlappingObjects.size();
|
||||
}
|
||||
|
||||
btCollisionObject* getOverlappingObject(int index)
|
||||
{
|
||||
return m_overlappingObjects[index];
|
||||
}
|
||||
|
||||
const btCollisionObject* getOverlappingObject(int index) const
|
||||
{
|
||||
return m_overlappingObjects[index];
|
||||
}
|
||||
|
||||
btAlignedObjectArray<btCollisionObject*>& getOverlappingPairs()
|
||||
{
|
||||
return m_overlappingObjects;
|
||||
}
|
||||
|
||||
const btAlignedObjectArray<btCollisionObject*> getOverlappingPairs() const
|
||||
{
|
||||
return m_overlappingObjects;
|
||||
}
|
||||
|
||||
//
|
||||
// internal cast
|
||||
//
|
||||
|
||||
static const btGhostObject* upcast(const btCollisionObject* colObj)
|
||||
{
|
||||
if (colObj->getInternalType()==CO_GHOST_OBJECT)
|
||||
return (const btGhostObject*)colObj;
|
||||
return 0;
|
||||
}
|
||||
static btGhostObject* upcast(btCollisionObject* colObj)
|
||||
{
|
||||
if (colObj->getInternalType()==CO_GHOST_OBJECT)
|
||||
return (btGhostObject*)colObj;
|
||||
return 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class btPairCachingGhostObject : public btGhostObject
|
||||
{
|
||||
btHashedOverlappingPairCache* m_hashPairCache;
|
||||
|
||||
public:
|
||||
|
||||
btPairCachingGhostObject();
|
||||
|
||||
virtual ~btPairCachingGhostObject();
|
||||
|
||||
///this method is mainly for expert/internal use only.
|
||||
virtual void addOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btBroadphaseProxy* thisProxy=0);
|
||||
|
||||
virtual void removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy=0);
|
||||
|
||||
btHashedOverlappingPairCache* getOverlappingPairCache()
|
||||
{
|
||||
return m_hashPairCache;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
///The btGhostPairCallback interfaces and forwards adding and removal of overlapping pairs from the btBroadphaseInterface to btGhostObject.
|
||||
class btGhostPairCallback : public btOverlappingPairCallback
|
||||
{
|
||||
|
||||
public:
|
||||
btGhostPairCallback()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~btGhostPairCallback()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
|
||||
{
|
||||
btCollisionObject* colObj0 = (btCollisionObject*) proxy0->m_clientObject;
|
||||
btCollisionObject* colObj1 = (btCollisionObject*) proxy1->m_clientObject;
|
||||
btGhostObject* ghost0 = btGhostObject::upcast(colObj0);
|
||||
btGhostObject* ghost1 = btGhostObject::upcast(colObj1);
|
||||
if (ghost0)
|
||||
ghost0->addOverlappingObjectInternal(proxy1, proxy0);
|
||||
if (ghost1)
|
||||
ghost1->addOverlappingObjectInternal(proxy0, proxy1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher)
|
||||
{
|
||||
btCollisionObject* colObj0 = (btCollisionObject*) proxy0->m_clientObject;
|
||||
btCollisionObject* colObj1 = (btCollisionObject*) proxy1->m_clientObject;
|
||||
btGhostObject* ghost0 = btGhostObject::upcast(colObj0);
|
||||
btGhostObject* ghost1 = btGhostObject::upcast(colObj1);
|
||||
if (ghost0)
|
||||
ghost0->removeOverlappingObjectInternal(proxy1,dispatcher,proxy0);
|
||||
if (ghost1)
|
||||
ghost1->removeOverlappingObjectInternal(proxy0,dispatcher,proxy1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy0,btDispatcher* dispatcher)
|
||||
{
|
||||
btAssert(0);
|
||||
//need to keep track of all ghost objects and call them here
|
||||
//m_hashPairCache->removeOverlappingPairsContainingProxy(proxy0,dispatcher);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
@ -55,7 +55,7 @@ btManifoldResult::btManifoldResult(btCollisionObject* body0,btCollisionObject* b
|
||||
|
||||
void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
|
||||
{
|
||||
assert(m_manifoldPtr);
|
||||
btAssert(m_manifoldPtr);
|
||||
//order in manifold needs to match
|
||||
|
||||
if (depth > m_manifoldPtr->getContactBreakingThreshold())
|
||||
@ -92,8 +92,8 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b
|
||||
newPt.m_partId1 = m_partId1;
|
||||
newPt.m_index0 = m_index0;
|
||||
newPt.m_index1 = m_index1;
|
||||
|
||||
///todo, check this for any side effects
|
||||
//printf("depth=%f\n",depth);
|
||||
///@todo, check this for any side effects
|
||||
if (insertIndex >= 0)
|
||||
{
|
||||
//const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex);
|
||||
|
@ -45,6 +45,8 @@ class btManifoldResult : public btDiscreteCollisionDetectorInterface::Result
|
||||
int m_partId1;
|
||||
int m_index0;
|
||||
int m_index1;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
btManifoldResult()
|
||||
@ -77,6 +79,7 @@ public:
|
||||
m_index1=index1;
|
||||
}
|
||||
|
||||
|
||||
virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth);
|
||||
|
||||
SIMD_FORCE_INLINE void refreshContactPoints()
|
||||
|
@ -24,7 +24,8 @@ subject to the following restrictions:
|
||||
//#include <stdio.h>
|
||||
#include "LinearMath/btQuickprof.h"
|
||||
|
||||
btSimulationIslandManager::btSimulationIslandManager()
|
||||
btSimulationIslandManager::btSimulationIslandManager():
|
||||
m_splitIslands(true)
|
||||
{
|
||||
}
|
||||
|
||||
@ -43,10 +44,10 @@ void btSimulationIslandManager::findUnions(btDispatcher* /* dispatcher */,btColl
|
||||
{
|
||||
|
||||
{
|
||||
btBroadphasePair* pairPtr = colWorld->getPairCache()->getOverlappingPairArrayPtr();
|
||||
|
||||
|
||||
for (int i=0;i<colWorld->getPairCache()->getNumOverlappingPairs();i++)
|
||||
{
|
||||
btBroadphasePair* pairPtr = colWorld->getPairCache()->getOverlappingPairArrayPtr();
|
||||
const btBroadphasePair& collisionPair = pairPtr[i];
|
||||
btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
|
||||
btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
|
||||
@ -143,11 +144,13 @@ class btPersistentManifoldSortPredicate
|
||||
};
|
||||
|
||||
|
||||
void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects)
|
||||
void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld)
|
||||
{
|
||||
|
||||
BT_PROFILE("islandUnionFindAndQuickSort");
|
||||
|
||||
btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray();
|
||||
|
||||
m_islandmanifold.resize(0);
|
||||
|
||||
//we are going to sort the unionfind array, and store the element id in the size
|
||||
@ -183,7 +186,7 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisio
|
||||
// printf("error in island management\n");
|
||||
}
|
||||
|
||||
assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
|
||||
btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
|
||||
if (colObj0->getIslandTag() == islandId)
|
||||
{
|
||||
if (colObj0->getActivationState()== ACTIVE_TAG)
|
||||
@ -210,7 +213,7 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisio
|
||||
// printf("error in island management\n");
|
||||
}
|
||||
|
||||
assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
|
||||
btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
|
||||
|
||||
if (colObj0->getIslandTag() == islandId)
|
||||
{
|
||||
@ -231,13 +234,14 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisio
|
||||
// printf("error in island management\n");
|
||||
}
|
||||
|
||||
assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
|
||||
btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
|
||||
|
||||
if (colObj0->getIslandTag() == islandId)
|
||||
{
|
||||
if ( colObj0->getActivationState() == ISLAND_SLEEPING)
|
||||
{
|
||||
colObj0->setActivationState( WANTS_DEACTIVATION);
|
||||
colObj0->setDeactivationTime(0.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -248,11 +252,11 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisio
|
||||
int i;
|
||||
int maxNumManifolds = dispatcher->getNumManifolds();
|
||||
|
||||
#define SPLIT_ISLANDS 1
|
||||
#ifdef SPLIT_ISLANDS
|
||||
//#define SPLIT_ISLANDS 1
|
||||
//#ifdef SPLIT_ISLANDS
|
||||
|
||||
|
||||
#endif //SPLIT_ISLANDS
|
||||
//#endif //SPLIT_ISLANDS
|
||||
|
||||
|
||||
for (i=0;i<maxNumManifolds ;i++)
|
||||
@ -262,7 +266,7 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisio
|
||||
btCollisionObject* colObj0 = static_cast<btCollisionObject*>(manifold->getBody0());
|
||||
btCollisionObject* colObj1 = static_cast<btCollisionObject*>(manifold->getBody1());
|
||||
|
||||
//todo: check sleeping conditions!
|
||||
///@todo: check sleeping conditions!
|
||||
if (((colObj0) && colObj0->getActivationState() != ISLAND_SLEEPING) ||
|
||||
((colObj1) && colObj1->getActivationState() != ISLAND_SLEEPING))
|
||||
{
|
||||
@ -276,24 +280,24 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisio
|
||||
{
|
||||
colObj0->activate();
|
||||
}
|
||||
#ifdef SPLIT_ISLANDS
|
||||
// //filtering for response
|
||||
if (dispatcher->needsResponse(colObj0,colObj1))
|
||||
m_islandmanifold.push_back(manifold);
|
||||
#endif //SPLIT_ISLANDS
|
||||
if(m_splitIslands)
|
||||
{
|
||||
//filtering for response
|
||||
if (dispatcher->needsResponse(colObj0,colObj1))
|
||||
m_islandmanifold.push_back(manifold);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// todo: this is random access, it can be walked 'cache friendly'!
|
||||
//
|
||||
void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback)
|
||||
///@todo: this is random access, it can be walked 'cache friendly'!
|
||||
void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld, IslandCallback* callback)
|
||||
{
|
||||
btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray();
|
||||
|
||||
buildIslands(dispatcher,collisionObjects);
|
||||
buildIslands(dispatcher,collisionWorld);
|
||||
|
||||
int endIslandIndex=1;
|
||||
int startIslandIndex;
|
||||
@ -301,84 +305,86 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
|
||||
|
||||
BT_PROFILE("processIslands");
|
||||
|
||||
#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))
|
||||
m_islandmanifold.quickSort(btPersistentManifoldSortPredicate());
|
||||
|
||||
//now process all active islands (sets of manifolds for now)
|
||||
|
||||
int startManifoldIndex = 0;
|
||||
int endManifoldIndex = 1;
|
||||
|
||||
//int islandId;
|
||||
|
||||
|
||||
|
||||
// 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)
|
||||
if(!m_splitIslands)
|
||||
{
|
||||
int islandId = getUnionFind().getElement(startIslandIndex).m_id;
|
||||
btPersistentManifold** manifold = dispatcher->getInternalManifoldPointer();
|
||||
int maxNumManifolds = dispatcher->getNumManifolds();
|
||||
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());
|
||||
|
||||
bool islandSleeping = false;
|
||||
|
||||
for (endIslandIndex = startIslandIndex;(endIslandIndex<numElem) && (getUnionFind().getElement(endIslandIndex).m_id == islandId);endIslandIndex++)
|
||||
{
|
||||
int i = getUnionFind().getElement(endIslandIndex).m_sz;
|
||||
btCollisionObject* colObj0 = collisionObjects[i];
|
||||
m_islandBodies.push_back(colObj0);
|
||||
if (!colObj0->isActive())
|
||||
islandSleeping = true;
|
||||
}
|
||||
|
||||
//we should do radix sort, it it much faster (O(n) instead of O (n log2(n))
|
||||
m_islandmanifold.quickSort(btPersistentManifoldSortPredicate());
|
||||
|
||||
//find the accompanying contact manifold for this islandId
|
||||
int numIslandManifolds = 0;
|
||||
btPersistentManifold** startManifold = 0;
|
||||
//now process all active islands (sets of manifolds for now)
|
||||
|
||||
if (startManifoldIndex<numManifolds)
|
||||
int startManifoldIndex = 0;
|
||||
int endManifoldIndex = 1;
|
||||
|
||||
//int islandId;
|
||||
|
||||
|
||||
|
||||
// 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)
|
||||
{
|
||||
int curIslandId = getIslandId(m_islandmanifold[startManifoldIndex]);
|
||||
if (curIslandId == islandId)
|
||||
{
|
||||
startManifold = &m_islandmanifold[startManifoldIndex];
|
||||
|
||||
for (endManifoldIndex = startManifoldIndex+1;(endManifoldIndex<numManifolds) && (islandId == getIslandId(m_islandmanifold[endManifoldIndex]));endManifoldIndex++)
|
||||
{
|
||||
int islandId = getUnionFind().getElement(startIslandIndex).m_id;
|
||||
|
||||
|
||||
bool islandSleeping = false;
|
||||
|
||||
for (endIslandIndex = startIslandIndex;(endIslandIndex<numElem) && (getUnionFind().getElement(endIslandIndex).m_id == islandId);endIslandIndex++)
|
||||
{
|
||||
int i = getUnionFind().getElement(endIslandIndex).m_sz;
|
||||
btCollisionObject* colObj0 = collisionObjects[i];
|
||||
m_islandBodies.push_back(colObj0);
|
||||
if (!colObj0->isActive())
|
||||
islandSleeping = true;
|
||||
}
|
||||
|
||||
|
||||
//find the accompanying contact manifold for this islandId
|
||||
int numIslandManifolds = 0;
|
||||
btPersistentManifold** startManifold = 0;
|
||||
|
||||
if (startManifoldIndex<numManifolds)
|
||||
{
|
||||
int curIslandId = getIslandId(m_islandmanifold[startManifoldIndex]);
|
||||
if (curIslandId == islandId)
|
||||
{
|
||||
startManifold = &m_islandmanifold[startManifoldIndex];
|
||||
|
||||
for (endManifoldIndex = startManifoldIndex+1;(endManifoldIndex<numManifolds) && (islandId == getIslandId(m_islandmanifold[endManifoldIndex]));endManifoldIndex++)
|
||||
{
|
||||
|
||||
}
|
||||
/// Process the actual simulation, only if not sleeping/deactivated
|
||||
numIslandManifolds = endManifoldIndex-startManifoldIndex;
|
||||
}
|
||||
/// Process the actual simulation, only if not sleeping/deactivated
|
||||
numIslandManifolds = endManifoldIndex-startManifoldIndex;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if (!islandSleeping)
|
||||
{
|
||||
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)
|
||||
{
|
||||
startManifoldIndex = endManifoldIndex;
|
||||
}
|
||||
|
||||
if (!islandSleeping)
|
||||
{
|
||||
callback->ProcessIsland(&m_islandBodies[0],m_islandBodies.size(),startManifold,numIslandManifolds, islandId);
|
||||
// printf("Island callback of size:%d bodies, %d manifolds\n",islandBodies.size(),numIslandManifolds);
|
||||
m_islandBodies.resize(0);
|
||||
}
|
||||
|
||||
if (numIslandManifolds)
|
||||
{
|
||||
startManifoldIndex = endManifoldIndex;
|
||||
}
|
||||
|
||||
m_islandBodies.resize(0);
|
||||
}
|
||||
#endif //SPLIT_ISLANDS
|
||||
|
||||
} // else if(!splitIslands)
|
||||
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ subject to the following restrictions:
|
||||
#include "BulletCollision/CollisionDispatch/btUnionFind.h"
|
||||
#include "btCollisionCreateFunc.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
#include "btCollisionObject.h"
|
||||
|
||||
class btCollisionObject;
|
||||
class btCollisionWorld;
|
||||
@ -35,6 +35,7 @@ class btSimulationIslandManager
|
||||
btAlignedObjectArray<btPersistentManifold*> m_islandmanifold;
|
||||
btAlignedObjectArray<btCollisionObject* > m_islandBodies;
|
||||
|
||||
bool m_splitIslands;
|
||||
|
||||
public:
|
||||
btSimulationIslandManager();
|
||||
@ -61,9 +62,18 @@ public:
|
||||
virtual void ProcessIsland(btCollisionObject** bodies,int numBodies,class btPersistentManifold** manifolds,int numManifolds, int islandId) = 0;
|
||||
};
|
||||
|
||||
void buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback);
|
||||
void buildAndProcessIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld, IslandCallback* callback);
|
||||
|
||||
void buildIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects);
|
||||
void buildIslands(btDispatcher* dispatcher,btCollisionWorld* colWorld);
|
||||
|
||||
bool getSplitIslands()
|
||||
{
|
||||
return m_splitIslands;
|
||||
}
|
||||
void setSplitIslands(bool doSplitIslands)
|
||||
{
|
||||
m_splitIslands = doSplitIslands;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
@ -21,7 +21,7 @@ subject to the following restrictions:
|
||||
//#include <stdio.h>
|
||||
|
||||
btSphereBoxCollisionAlgorithm::btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped)
|
||||
: btCollisionAlgorithm(ci),
|
||||
: btActivatingCollisionAlgorithm(ci,col0,col1),
|
||||
m_ownManifold(false),
|
||||
m_manifoldPtr(mf),
|
||||
m_isSwapped(isSwapped)
|
||||
|
@ -16,7 +16,7 @@ subject to the following restrictions:
|
||||
#ifndef SPHERE_BOX_COLLISION_ALGORITHM_H
|
||||
#define SPHERE_BOX_COLLISION_ALGORITHM_H
|
||||
|
||||
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
|
||||
#include "btActivatingCollisionAlgorithm.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
|
||||
class btPersistentManifold;
|
||||
@ -26,7 +26,7 @@ class btPersistentManifold;
|
||||
|
||||
/// btSphereBoxCollisionAlgorithm provides sphere-box collision detection.
|
||||
/// Other features are frame-coherency (persistent data) and collision response.
|
||||
class btSphereBoxCollisionAlgorithm : public btCollisionAlgorithm
|
||||
class btSphereBoxCollisionAlgorithm : public btActivatingCollisionAlgorithm
|
||||
{
|
||||
bool m_ownManifold;
|
||||
btPersistentManifold* m_manifoldPtr;
|
||||
|
4
extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
vendored
4
extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
vendored
@ -19,7 +19,7 @@ subject to the following restrictions:
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||
|
||||
btSphereSphereCollisionAlgorithm::btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1)
|
||||
: btCollisionAlgorithm(ci),
|
||||
: btActivatingCollisionAlgorithm(ci,col0,col1),
|
||||
m_ownManifold(false),
|
||||
m_manifoldPtr(mf)
|
||||
{
|
||||
@ -78,7 +78,7 @@ void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0
|
||||
}
|
||||
|
||||
///point on A (worldspace)
|
||||
btVector3 pos0 = col0->getWorldTransform().getOrigin() - radius0 * normalOnSurfaceB;
|
||||
///btVector3 pos0 = col0->getWorldTransform().getOrigin() - radius0 * normalOnSurfaceB;
|
||||
///point on B (worldspace)
|
||||
btVector3 pos1 = col1->getWorldTransform().getOrigin() + radius1* normalOnSurfaceB;
|
||||
|
||||
|
@ -16,7 +16,7 @@ subject to the following restrictions:
|
||||
#ifndef SPHERE_SPHERE_COLLISION_ALGORITHM_H
|
||||
#define SPHERE_SPHERE_COLLISION_ALGORITHM_H
|
||||
|
||||
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
|
||||
#include "btActivatingCollisionAlgorithm.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
|
||||
#include "btCollisionDispatcher.h"
|
||||
@ -26,7 +26,7 @@ class btPersistentManifold;
|
||||
/// btSphereSphereCollisionAlgorithm provides sphere-sphere collision detection.
|
||||
/// Other features are frame-coherency (persistent data) and collision response.
|
||||
/// Also provides the most basic sample for custom/user btCollisionAlgorithm
|
||||
class btSphereSphereCollisionAlgorithm : public btCollisionAlgorithm
|
||||
class btSphereSphereCollisionAlgorithm : public btActivatingCollisionAlgorithm
|
||||
{
|
||||
bool m_ownManifold;
|
||||
btPersistentManifold* m_manifoldPtr;
|
||||
@ -35,7 +35,7 @@ public:
|
||||
btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
|
||||
|
||||
btSphereSphereCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
|
||||
: btCollisionAlgorithm(ci) {}
|
||||
: btActivatingCollisionAlgorithm(ci) {}
|
||||
|
||||
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
|
6
extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
vendored
6
extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
vendored
@ -22,7 +22,7 @@ subject to the following restrictions:
|
||||
|
||||
|
||||
btSphereTriangleCollisionAlgorithm::btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1,bool swapped)
|
||||
: btCollisionAlgorithm(ci),
|
||||
: btActivatingCollisionAlgorithm(ci,col0,col1),
|
||||
m_ownManifold(false),
|
||||
m_manifoldPtr(mf),
|
||||
m_swapped(swapped)
|
||||
@ -56,10 +56,10 @@ void btSphereTriangleCollisionAlgorithm::processCollision (btCollisionObject* co
|
||||
|
||||
/// report a contact. internally this will be kept persistent, and contact reduction is done
|
||||
resultOut->setPersistentManifold(m_manifoldPtr);
|
||||
SphereTriangleDetector detector(sphere,triangle);
|
||||
SphereTriangleDetector detector(sphere,triangle, m_manifoldPtr->getContactBreakingThreshold());
|
||||
|
||||
btDiscreteCollisionDetectorInterface::ClosestPointInput input;
|
||||
input.m_maximumDistanceSquared = btScalar(1e30);//todo: tighter bounds
|
||||
input.m_maximumDistanceSquared = btScalar(1e30);///@todo: tighter bounds
|
||||
input.m_transformA = sphereObj->getWorldTransform();
|
||||
input.m_transformB = triObj->getWorldTransform();
|
||||
|
||||
|
6
extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
vendored
6
extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
vendored
@ -16,7 +16,7 @@ subject to the following restrictions:
|
||||
#ifndef SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
|
||||
#define SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
|
||||
|
||||
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
|
||||
#include "btActivatingCollisionAlgorithm.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
|
||||
class btPersistentManifold;
|
||||
@ -25,7 +25,7 @@ class btPersistentManifold;
|
||||
/// btSphereSphereCollisionAlgorithm provides sphere-sphere collision detection.
|
||||
/// Other features are frame-coherency (persistent data) and collision response.
|
||||
/// Also provides the most basic sample for custom/user btCollisionAlgorithm
|
||||
class btSphereTriangleCollisionAlgorithm : public btCollisionAlgorithm
|
||||
class btSphereTriangleCollisionAlgorithm : public btActivatingCollisionAlgorithm
|
||||
{
|
||||
bool m_ownManifold;
|
||||
btPersistentManifold* m_manifoldPtr;
|
||||
@ -35,7 +35,7 @@ public:
|
||||
btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool swapped);
|
||||
|
||||
btSphereTriangleCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
|
||||
: btCollisionAlgorithm(ci) {}
|
||||
: btActivatingCollisionAlgorithm(ci) {}
|
||||
|
||||
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
|
@ -14,8 +14,6 @@ subject to the following restrictions:
|
||||
*/
|
||||
|
||||
#include "btUnionFind.h"
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -98,8 +98,8 @@ class btUnionFind
|
||||
|
||||
int find(int x)
|
||||
{
|
||||
//assert(x < m_N);
|
||||
//assert(x >= 0);
|
||||
//btAssert(x < m_N);
|
||||
//btAssert(x >= 0);
|
||||
|
||||
while (x != m_elements[x].m_id)
|
||||
{
|
||||
@ -110,8 +110,8 @@ class btUnionFind
|
||||
m_elements[x].m_id = m_elements[m_elements[x].m_id].m_id;
|
||||
#endif //
|
||||
x = m_elements[x].m_id;
|
||||
//assert(x < m_N);
|
||||
//assert(x >= 0);
|
||||
//btAssert(x < m_N);
|
||||
//btAssert(x >= 0);
|
||||
|
||||
}
|
||||
return x;
|
||||
|
@ -19,7 +19,7 @@ subject to the following restrictions:
|
||||
#include "btPolyhedralConvexShape.h"
|
||||
#include "btCollisionMargin.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||
#include "LinearMath/btPoint3.h"
|
||||
#include "LinearMath/btVector3.h"
|
||||
#include "LinearMath/btMinMax.h"
|
||||
|
||||
///The btBoxShape is a box primitive around the origin, its sides axis aligned with length specified by half extents, in local shape coordinates. When used as part of a btCollisionObject or btRigidBody it will be an oriented box in world space.
|
||||
@ -45,8 +45,6 @@ public:
|
||||
}
|
||||
|
||||
|
||||
virtual int getShapeType() const { return BOX_SHAPE_PROXYTYPE;}
|
||||
|
||||
virtual btVector3 localGetSupportingVertex(const btVector3& vec) const
|
||||
{
|
||||
btVector3 halfExtents = getHalfExtentsWithoutMargin();
|
||||
@ -82,8 +80,10 @@ public:
|
||||
}
|
||||
|
||||
|
||||
btBoxShape( const btVector3& boxHalfExtents)
|
||||
btBoxShape( const btVector3& boxHalfExtents)
|
||||
: btPolyhedralConvexShape()
|
||||
{
|
||||
m_shapeType = BOX_SHAPE_PROXYTYPE;
|
||||
btVector3 margin(getMargin(),getMargin(),getMargin());
|
||||
m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin;
|
||||
};
|
||||
@ -117,7 +117,7 @@ public:
|
||||
|
||||
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
|
||||
|
||||
virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const
|
||||
virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const
|
||||
{
|
||||
//this plane might not be aligned...
|
||||
btVector4 plane ;
|
||||
@ -161,36 +161,30 @@ public:
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.));
|
||||
plane[3] = -halfExtents.x();
|
||||
plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.),-halfExtents.x());
|
||||
break;
|
||||
case 1:
|
||||
plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.));
|
||||
plane[3] = -halfExtents.x();
|
||||
plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.),-halfExtents.x());
|
||||
break;
|
||||
case 2:
|
||||
plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.));
|
||||
plane[3] = -halfExtents.y();
|
||||
plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.),-halfExtents.y());
|
||||
break;
|
||||
case 3:
|
||||
plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.));
|
||||
plane[3] = -halfExtents.y();
|
||||
plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.),-halfExtents.y());
|
||||
break;
|
||||
case 4:
|
||||
plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.));
|
||||
plane[3] = -halfExtents.z();
|
||||
plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.),-halfExtents.z());
|
||||
break;
|
||||
case 5:
|
||||
plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.));
|
||||
plane[3] = -halfExtents.z();
|
||||
plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.),-halfExtents.z());
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
btAssert(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const
|
||||
virtual void getEdge(int i,btVector3& pa,btVector3& pb) const
|
||||
//virtual void getEdge(int i,Edge& edge) const
|
||||
{
|
||||
int edgeVert0 = 0;
|
||||
@ -261,7 +255,7 @@ public:
|
||||
|
||||
|
||||
|
||||
virtual bool isInside(const btPoint3& pt,btScalar tolerance) const
|
||||
virtual bool isInside(const btVector3& pt,btScalar tolerance) const
|
||||
{
|
||||
btVector3 halfExtents = getHalfExtentsWithoutMargin();
|
||||
|
||||
@ -312,7 +306,7 @@ public:
|
||||
penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(-1.));
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
btAssert(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ m_bvh(0),
|
||||
m_useQuantizedAabbCompression(useQuantizedAabbCompression),
|
||||
m_ownsBvh(false)
|
||||
{
|
||||
m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;
|
||||
//construct bvh from meshInterface
|
||||
#ifndef DISABLE_BVH
|
||||
|
||||
@ -57,6 +58,7 @@ m_bvh(0),
|
||||
m_useQuantizedAabbCompression(useQuantizedAabbCompression),
|
||||
m_ownsBvh(false)
|
||||
{
|
||||
m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;
|
||||
//construct bvh from meshInterface
|
||||
#ifndef DISABLE_BVH
|
||||
|
||||
@ -141,10 +143,19 @@ void btBvhTriangleMeshShape::performRaycast (btTriangleCallback* callback, const
|
||||
for (int j=2;j>=0;j--)
|
||||
{
|
||||
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
|
||||
|
||||
btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
|
||||
|
||||
m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
|
||||
|
||||
if (type == PHY_FLOAT)
|
||||
{
|
||||
float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
|
||||
|
||||
m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
|
||||
}
|
||||
else
|
||||
{
|
||||
double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
|
||||
|
||||
m_triangle[j] = btVector3(btScalar(graphicsbase[0])*meshScaling.getX(),btScalar(graphicsbase[1])*meshScaling.getY(),btScalar(graphicsbase[2])*meshScaling.getZ());
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform ray vs. triangle collision here */
|
||||
@ -202,9 +213,18 @@ void btBvhTriangleMeshShape::performConvexcast (btTriangleCallback* callback, co
|
||||
{
|
||||
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
|
||||
|
||||
btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
|
||||
if (type == PHY_FLOAT)
|
||||
{
|
||||
float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
|
||||
|
||||
m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
|
||||
m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
|
||||
}
|
||||
else
|
||||
{
|
||||
double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
|
||||
|
||||
m_triangle[j] = btVector3(btScalar(graphicsbase[0])*meshScaling.getX(),btScalar(graphicsbase[1])*meshScaling.getY(),btScalar(graphicsbase[2])*meshScaling.getZ());
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform ray vs. triangle collision here */
|
||||
@ -279,12 +299,24 @@ void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,co
|
||||
#ifdef DEBUG_TRIANGLE_MESH
|
||||
printf("%d ,",graphicsindex);
|
||||
#endif //DEBUG_TRIANGLE_MESH
|
||||
btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
|
||||
if (type == PHY_FLOAT)
|
||||
{
|
||||
float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
|
||||
|
||||
m_triangle[j] = btVector3(
|
||||
graphicsbase[0]*meshScaling.getX(),
|
||||
graphicsbase[1]*meshScaling.getY(),
|
||||
graphicsbase[2]*meshScaling.getZ());
|
||||
}
|
||||
else
|
||||
{
|
||||
double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
|
||||
|
||||
m_triangle[j] = btVector3(
|
||||
graphicsbase[0]*meshScaling.getX(),
|
||||
graphicsbase[1]*meshScaling.getY(),
|
||||
graphicsbase[2]*meshScaling.getZ());
|
||||
m_triangle[j] = btVector3(
|
||||
btScalar(graphicsbase[0])*meshScaling.getX(),
|
||||
btScalar(graphicsbase[1])*meshScaling.getY(),
|
||||
btScalar(graphicsbase[2])*meshScaling.getZ());
|
||||
}
|
||||
#ifdef DEBUG_TRIANGLE_MESH
|
||||
printf("triangle vertices:%f,%f,%f\n",triangle[j].x(),triangle[j].y(),triangle[j].z());
|
||||
#endif //DEBUG_TRIANGLE_MESH
|
||||
|
@ -37,7 +37,7 @@ public:
|
||||
|
||||
BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
btBvhTriangleMeshShape() :btTriangleMeshShape(0),m_bvh(0),m_ownsBvh(false) {};
|
||||
btBvhTriangleMeshShape() : btTriangleMeshShape(0),m_bvh(0),m_ownsBvh(false) {m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;};
|
||||
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
|
||||
@ -50,10 +50,7 @@ public:
|
||||
return m_ownsBvh;
|
||||
}
|
||||
|
||||
virtual int getShapeType() const
|
||||
{
|
||||
return TRIANGLE_MESH_SHAPE_PROXYTYPE;
|
||||
}
|
||||
|
||||
|
||||
void performRaycast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget);
|
||||
void performConvexcast (btTriangleCallback* callback, const btVector3& boxSource, const btVector3& boxTarget, const btVector3& boxMin, const btVector3& boxMax);
|
||||
|
@ -19,8 +19,9 @@ subject to the following restrictions:
|
||||
#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
|
||||
#include "LinearMath/btQuaternion.h"
|
||||
|
||||
btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height)
|
||||
btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) : btConvexInternalShape ()
|
||||
{
|
||||
m_shapeType = CAPSULE_SHAPE_PROXYTYPE;
|
||||
m_upAxis = 1;
|
||||
m_implicitShapeDimensions.setValue(radius,0.5f*height,radius);
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ protected:
|
||||
|
||||
protected:
|
||||
///only used for btCapsuleShapeZ and btCapsuleShapeX subclasses.
|
||||
btCapsuleShape() {};
|
||||
btCapsuleShape() : btConvexInternalShape() {m_shapeType = CAPSULE_SHAPE_PROXYTYPE;};
|
||||
|
||||
public:
|
||||
btCapsuleShape(btScalar radius,btScalar height);
|
||||
@ -43,15 +43,13 @@ public:
|
||||
|
||||
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
|
||||
|
||||
virtual int getShapeType() const { return CAPSULE_SHAPE_PROXYTYPE; }
|
||||
|
||||
virtual void getAabb (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
|
||||
{
|
||||
btVector3 halfExtents(getRadius(),getRadius(),getRadius());
|
||||
halfExtents[m_upAxis] = getRadius() + getHalfHeight();
|
||||
halfExtents += btVector3(getMargin(),getMargin(),getMargin());
|
||||
btMatrix3x3 abs_b = t.getBasis().absolute();
|
||||
btPoint3 center = t.getOrigin();
|
||||
btVector3 center = t.getOrigin();
|
||||
btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));
|
||||
|
||||
aabbMin = center - extent;
|
||||
|
@ -16,6 +16,9 @@ subject to the following restrictions:
|
||||
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
|
||||
|
||||
|
||||
btScalar gContactThresholdFactor=btScalar(0.02);
|
||||
|
||||
|
||||
/*
|
||||
Make sure this dummy function never changes so that it
|
||||
can be used by probes that are checking whether the
|
||||
@ -42,8 +45,13 @@ void btCollisionShape::getBoundingSphere(btVector3& center,btScalar& radius) con
|
||||
center = (aabbMin+aabbMax)*btScalar(0.5);
|
||||
}
|
||||
|
||||
btScalar btCollisionShape::getContactBreakingThreshold() const
|
||||
{
|
||||
return getAngularMotionDisc() * gContactThresholdFactor;
|
||||
}
|
||||
btScalar btCollisionShape::getAngularMotionDisc() const
|
||||
{
|
||||
///@todo cache this value, to improve performance
|
||||
btVector3 center;
|
||||
btScalar disc;
|
||||
getBoundingSphere(center,disc);
|
||||
@ -65,7 +73,7 @@ void btCollisionShape::calculateTemporalAabb(const btTransform& curTrans,const b
|
||||
|
||||
// add linear motion
|
||||
btVector3 linMotion = linvel*timeStep;
|
||||
//todo: simd would have a vector max/min operation, instead of per-element access
|
||||
///@todo: simd would have a vector max/min operation, instead of per-element access
|
||||
if (linMotion.x() > btScalar(0.))
|
||||
temporalAabbMaxx += linMotion.x();
|
||||
else
|
||||
|
@ -19,20 +19,21 @@ subject to the following restrictions:
|
||||
#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
|
||||
|
||||
///The btCollisionShape class provides an interface for collision shapes that can be shared among btCollisionObjects.
|
||||
class btCollisionShape
|
||||
{
|
||||
|
||||
protected:
|
||||
int m_shapeType;
|
||||
void* m_userPointer;
|
||||
|
||||
public:
|
||||
|
||||
btCollisionShape() : m_userPointer(0)
|
||||
btCollisionShape() : m_shapeType (INVALID_SHAPE_PROXYTYPE), m_userPointer(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~btCollisionShape()
|
||||
{
|
||||
}
|
||||
@ -45,6 +46,8 @@ public:
|
||||
///getAngularMotionDisc returns the maximus radius needed for Conservative Advancement to handle time-of-impact with rotations.
|
||||
virtual btScalar getAngularMotionDisc() const;
|
||||
|
||||
virtual btScalar getContactBreakingThreshold() const;
|
||||
|
||||
|
||||
///calculateTemporalAabb calculates the enclosing aabb for the moving object over interval [0..timeStep)
|
||||
///result is conservative
|
||||
@ -76,7 +79,7 @@ public:
|
||||
return btBroadphaseProxy::isInfinite(getShapeType());
|
||||
}
|
||||
|
||||
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) const = 0;
|
||||
@ -87,13 +90,13 @@ public:
|
||||
#endif //__SPU__
|
||||
|
||||
|
||||
|
||||
int getShapeType() const { return m_shapeType; }
|
||||
virtual void setMargin(btScalar margin) = 0;
|
||||
virtual btScalar getMargin() const = 0;
|
||||
|
||||
|
||||
///optional user data pointer
|
||||
void setUserPointer(void* userPtr)
|
||||
void setUserPointer(void* userPtr)
|
||||
{
|
||||
m_userPointer = userPtr;
|
||||
}
|
||||
|
@ -17,16 +17,22 @@ subject to the following restrictions:
|
||||
#include "btCollisionShape.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
|
||||
|
||||
btCompoundShape::btCompoundShape()
|
||||
:m_localAabbMin(btScalar(1e30),btScalar(1e30),btScalar(1e30)),
|
||||
btCompoundShape::btCompoundShape(bool enableDynamicAabbTree)
|
||||
: m_localAabbMin(btScalar(1e30),btScalar(1e30),btScalar(1e30)),
|
||||
m_localAabbMax(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)),
|
||||
m_collisionMargin(btScalar(0.)),
|
||||
m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),
|
||||
m_dynamicAabbTree(0)
|
||||
m_dynamicAabbTree(0),
|
||||
m_updateRevision(1)
|
||||
{
|
||||
void* mem = btAlignedAlloc(sizeof(btDbvt),16);
|
||||
m_dynamicAabbTree = new(mem) btDbvt();
|
||||
btAssert(mem==m_dynamicAabbTree);
|
||||
m_shapeType = COMPOUND_SHAPE_PROXYTYPE;
|
||||
|
||||
if (enableDynamicAabbTree)
|
||||
{
|
||||
void* mem = btAlignedAlloc(sizeof(btDbvt),16);
|
||||
m_dynamicAabbTree = new(mem) btDbvt();
|
||||
btAssert(mem==m_dynamicAabbTree);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -41,6 +47,7 @@ btCompoundShape::~btCompoundShape()
|
||||
|
||||
void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisionShape* shape)
|
||||
{
|
||||
m_updateRevision++;
|
||||
//m_childTransforms.push_back(localTransform);
|
||||
//m_childShapes.push_back(shape);
|
||||
btCompoundShapeChild child;
|
||||
@ -49,6 +56,7 @@ void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisio
|
||||
child.m_childShapeType = shape->getShapeType();
|
||||
child.m_childMargin = shape->getMargin();
|
||||
|
||||
|
||||
//extend the local aabbMin/aabbMax
|
||||
btVector3 localAabbMin,localAabbMax;
|
||||
shape->getAabb(localTransform,localAabbMin,localAabbMax);
|
||||
@ -72,10 +80,29 @@ void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisio
|
||||
}
|
||||
|
||||
m_children.push_back(child);
|
||||
|
||||
}
|
||||
|
||||
void btCompoundShape::updateChildTransform(int childIndex, const btTransform& newChildTransform)
|
||||
{
|
||||
m_children[childIndex].m_transform = newChildTransform;
|
||||
|
||||
if (m_dynamicAabbTree)
|
||||
{
|
||||
///update the dynamic aabb tree
|
||||
btVector3 localAabbMin,localAabbMax;
|
||||
m_children[childIndex].m_childShape->getAabb(newChildTransform,localAabbMin,localAabbMax);
|
||||
ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
|
||||
int index = m_children.size()-1;
|
||||
m_dynamicAabbTree->update(m_children[childIndex].m_node,bounds);
|
||||
}
|
||||
|
||||
recalculateLocalAabb();
|
||||
}
|
||||
|
||||
void btCompoundShape::removeChildShapeByIndex(int childShapeIndex)
|
||||
{
|
||||
m_updateRevision++;
|
||||
btAssert(childShapeIndex >=0 && childShapeIndex < m_children.size());
|
||||
if (m_dynamicAabbTree)
|
||||
{
|
||||
@ -86,8 +113,11 @@ void btCompoundShape::removeChildShapeByIndex(int childShapeIndex)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void btCompoundShape::removeChildShape(btCollisionShape* shape)
|
||||
{
|
||||
m_updateRevision++;
|
||||
// Find the children containing the shape specified, and remove those children.
|
||||
//note: there might be multiple children using the same shape!
|
||||
for(int i = m_children.size()-1; i >= 0 ; i--)
|
||||
@ -97,6 +127,8 @@ void btCompoundShape::removeChildShape(btCollisionShape* shape)
|
||||
m_children.swap(i,m_children.size()-1);
|
||||
m_children.pop_back();
|
||||
//remove it from the m_dynamicAabbTree too
|
||||
//@todo: this leads to problems due to caching in the btCompoundCollisionAlgorithm
|
||||
//so effectively, removeChildShape is broken at the moment
|
||||
//m_dynamicAabbTree->remove(m_aabbProxies[i]);
|
||||
//m_aabbProxies.swap(i,m_children.size()-1);
|
||||
//m_aabbProxies.pop_back();
|
||||
@ -112,6 +144,7 @@ void btCompoundShape::recalculateLocalAabb()
|
||||
{
|
||||
// Recalculate the local aabb
|
||||
// Brute force, it iterates over all the shapes left.
|
||||
|
||||
m_localAabbMin = btVector3(btScalar(1e30),btScalar(1e30),btScalar(1e30));
|
||||
m_localAabbMax = btVector3(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
|
||||
|
||||
@ -134,19 +167,27 @@ void btCompoundShape::recalculateLocalAabb()
|
||||
void btCompoundShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
|
||||
{
|
||||
btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin);
|
||||
localHalfExtents += btVector3(getMargin(),getMargin(),getMargin());
|
||||
btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin);
|
||||
|
||||
//avoid an illegal AABB when there are no children
|
||||
if (!m_children.size())
|
||||
{
|
||||
localHalfExtents.setValue(0,0,0);
|
||||
localCenter.setValue(0,0,0);
|
||||
}
|
||||
localHalfExtents += btVector3(getMargin(),getMargin(),getMargin());
|
||||
|
||||
|
||||
btMatrix3x3 abs_b = trans.getBasis().absolute();
|
||||
|
||||
btPoint3 center = trans(localCenter);
|
||||
btVector3 center = trans(localCenter);
|
||||
|
||||
btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
|
||||
abs_b[1].dot(localHalfExtents),
|
||||
abs_b[2].dot(localHalfExtents));
|
||||
aabbMin = center-extent;
|
||||
aabbMax = center+extent;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void btCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
|
||||
@ -178,7 +219,9 @@ void btCompoundShape::calculatePrincipalAxisTransform(btScalar* masses, btTransf
|
||||
|
||||
btScalar totalMass = 0;
|
||||
btVector3 center(0, 0, 0);
|
||||
for (int k = 0; k < n; k++)
|
||||
int k;
|
||||
|
||||
for (k = 0; k < n; k++)
|
||||
{
|
||||
center += m_children[k].m_transform.getOrigin() * masses[k];
|
||||
totalMass += masses[k];
|
||||
@ -187,7 +230,7 @@ void btCompoundShape::calculatePrincipalAxisTransform(btScalar* masses, btTransf
|
||||
principal.setOrigin(center);
|
||||
|
||||
btMatrix3x3 tensor(0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
for (int k = 0; k < n; k++)
|
||||
for ( k = 0; k < n; k++)
|
||||
{
|
||||
btVector3 i;
|
||||
m_children[k].m_childShape->calculateLocalInertia(masses[k], i);
|
||||
|
@ -46,23 +46,26 @@ SIMD_FORCE_INLINE bool operator==(const btCompoundShapeChild& c1, const btCompou
|
||||
c1.m_childMargin == c2.m_childMargin );
|
||||
}
|
||||
|
||||
/// btCompoundShape allows to store multiple other btCollisionShapes
|
||||
/// The btCompoundShape allows to store multiple other btCollisionShapes
|
||||
/// This allows for moving concave collision objects. This is more general then the static concave btBvhTriangleMeshShape.
|
||||
/// It has an (optional) dynamic aabb tree to accelerate early rejection tests.
|
||||
/// @todo: This aabb tree can also be use to speed up ray tests on btCompoundShape, see http://code.google.com/p/bullet/issues/detail?id=25
|
||||
/// Currently, removal of child shapes is only supported when disabling the aabb tree (pass 'false' in the constructor of btCompoundShape)
|
||||
ATTRIBUTE_ALIGNED16(class) btCompoundShape : public btCollisionShape
|
||||
{
|
||||
//btAlignedObjectArray<btTransform> m_childTransforms;
|
||||
//btAlignedObjectArray<btCollisionShape*> m_childShapes;
|
||||
btAlignedObjectArray<btCompoundShapeChild> m_children;
|
||||
btVector3 m_localAabbMin;
|
||||
btVector3 m_localAabbMax;
|
||||
|
||||
//btOptimizedBvh* m_aabbTree;
|
||||
btDbvt* m_dynamicAabbTree;
|
||||
|
||||
///increment m_updateRevision when adding/removing/replacing child shapes, so that some caches can be updated
|
||||
int m_updateRevision;
|
||||
|
||||
public:
|
||||
BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
btCompoundShape();
|
||||
btCompoundShape(bool enableDynamicAabbTree = true);
|
||||
|
||||
virtual ~btCompoundShape();
|
||||
|
||||
@ -88,15 +91,18 @@ public:
|
||||
return m_children[index].m_childShape;
|
||||
}
|
||||
|
||||
btTransform getChildTransform(int index)
|
||||
btTransform& getChildTransform(int 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;
|
||||
}
|
||||
|
||||
///set a new transform for a child, and update internal data structures (local aabb and dynamic tree)
|
||||
void updateChildTransform(int childIndex, const btTransform& newChildTransform);
|
||||
|
||||
|
||||
btCompoundShapeChild* getChildList()
|
||||
{
|
||||
@ -121,8 +127,6 @@ public:
|
||||
|
||||
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
|
||||
|
||||
virtual int getShapeType() const { return COMPOUND_SHAPE_PROXYTYPE;}
|
||||
|
||||
virtual void setMargin(btScalar margin)
|
||||
{
|
||||
m_collisionMargin = margin;
|
||||
@ -151,6 +155,10 @@ public:
|
||||
///of the collision object by the principal transform.
|
||||
void calculatePrincipalAxisTransform(btScalar* masses, btTransform& principal, btVector3& inertia) const;
|
||||
|
||||
int getUpdateRevision() const
|
||||
{
|
||||
return m_updateRevision;
|
||||
}
|
||||
|
||||
private:
|
||||
btScalar m_collisionMargin;
|
||||
|
@ -20,6 +20,16 @@ subject to the following restrictions:
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
|
||||
#include "btTriangleCallback.h"
|
||||
|
||||
/// PHY_ScalarType enumerates possible scalar types.
|
||||
/// See the btStridingMeshInterface or btHeightfieldTerrainShape for its use
|
||||
typedef enum PHY_ScalarType {
|
||||
PHY_FLOAT,
|
||||
PHY_DOUBLE,
|
||||
PHY_INTEGER,
|
||||
PHY_SHORT,
|
||||
PHY_FIXEDPOINT88,
|
||||
PHY_UCHAR
|
||||
} PHY_ScalarType;
|
||||
|
||||
///The btConcaveShape class provides an interface for non-moving (static) concave shapes.
|
||||
///It has been implemented by the btStaticPlaneShape, btBvhTriangleMeshShape and btHeightfieldTerrainShape.
|
||||
|
@ -14,14 +14,14 @@ subject to the following restrictions:
|
||||
*/
|
||||
|
||||
#include "btConeShape.h"
|
||||
#include "LinearMath/btPoint3.h"
|
||||
|
||||
|
||||
|
||||
btConeShape::btConeShape (btScalar radius,btScalar height):
|
||||
btConeShape::btConeShape (btScalar radius,btScalar height): btConvexInternalShape (),
|
||||
m_radius (radius),
|
||||
m_height(height)
|
||||
{
|
||||
m_shapeType = CONE_SHAPE_PROXYTYPE;
|
||||
setConeUpIndex(1);
|
||||
btVector3 halfExtents;
|
||||
m_sinAngle = (m_radius / btSqrt(m_radius * m_radius + m_height * m_height));
|
||||
@ -60,7 +60,7 @@ void btConeShape::setConeUpIndex(int upIndex)
|
||||
m_coneIndices[2] = 1;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
btAssert(0);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -69,9 +69,6 @@ public:
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual int getShapeType() const { return CONE_SHAPE_PROXYTYPE; }
|
||||
|
||||
virtual const char* getName()const
|
||||
{
|
||||
return "Cone";
|
||||
|
@ -19,16 +19,17 @@ subject to the following restrictions:
|
||||
|
||||
|
||||
|
||||
btConvexHullShape ::btConvexHullShape (const btScalar* points,int numPoints,int stride)
|
||||
btConvexHullShape ::btConvexHullShape (const btScalar* points,int numPoints,int stride) : btPolyhedralConvexShape ()
|
||||
{
|
||||
m_points.resize(numPoints);
|
||||
m_shapeType = CONVEX_HULL_SHAPE_PROXYTYPE;
|
||||
m_unscaledPoints.resize(numPoints);
|
||||
|
||||
unsigned char* pointsBaseAddress = (unsigned char*)points;
|
||||
|
||||
for (int i=0;i<numPoints;i++)
|
||||
{
|
||||
btPoint3* point = (btPoint3*)(pointsBaseAddress + i*stride);
|
||||
m_points[i] = point[0];
|
||||
btVector3* point = (btVector3*)(pointsBaseAddress + i*stride);
|
||||
m_unscaledPoints[i] = point[0];
|
||||
}
|
||||
|
||||
recalcLocalAabb();
|
||||
@ -43,9 +44,9 @@ void btConvexHullShape::setLocalScaling(const btVector3& scaling)
|
||||
recalcLocalAabb();
|
||||
}
|
||||
|
||||
void btConvexHullShape::addPoint(const btPoint3& point)
|
||||
void btConvexHullShape::addPoint(const btVector3& point)
|
||||
{
|
||||
m_points.push_back(point);
|
||||
m_unscaledPoints.push_back(point);
|
||||
recalcLocalAabb();
|
||||
|
||||
}
|
||||
@ -67,9 +68,9 @@ btVector3 btConvexHullShape::localGetSupportingVertexWithoutMargin(const btVecto
|
||||
}
|
||||
|
||||
|
||||
for (int i=0;i<m_points.size();i++)
|
||||
for (int i=0;i<m_unscaledPoints.size();i++)
|
||||
{
|
||||
btPoint3 vtx = m_points[i] * m_localScaling;
|
||||
btVector3 vtx = m_unscaledPoints[i] * m_localScaling;
|
||||
|
||||
newDot = vec.dot(vtx);
|
||||
if (newDot > maxDot)
|
||||
@ -91,9 +92,9 @@ void btConvexHullShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const
|
||||
supportVerticesOut[i][3] = btScalar(-1e30);
|
||||
}
|
||||
}
|
||||
for (int i=0;i<m_points.size();i++)
|
||||
for (int i=0;i<m_unscaledPoints.size();i++)
|
||||
{
|
||||
btPoint3 vtx = m_points[i] * m_localScaling;
|
||||
btVector3 vtx = getScaledPoint(i);
|
||||
|
||||
for (int j=0;j<numVectors;j++)
|
||||
{
|
||||
@ -144,26 +145,26 @@ btVector3 btConvexHullShape::localGetSupportingVertex(const btVector3& vec)const
|
||||
//Please note that you can debug-draw btConvexHullShape with the Raytracer Demo
|
||||
int btConvexHullShape::getNumVertices() const
|
||||
{
|
||||
return m_points.size();
|
||||
return m_unscaledPoints.size();
|
||||
}
|
||||
|
||||
int btConvexHullShape::getNumEdges() const
|
||||
{
|
||||
return m_points.size();
|
||||
return m_unscaledPoints.size();
|
||||
}
|
||||
|
||||
void btConvexHullShape::getEdge(int i,btPoint3& pa,btPoint3& pb) const
|
||||
void btConvexHullShape::getEdge(int i,btVector3& pa,btVector3& pb) const
|
||||
{
|
||||
|
||||
int index0 = i%m_points.size();
|
||||
int index1 = (i+1)%m_points.size();
|
||||
pa = m_points[index0]*m_localScaling;
|
||||
pb = m_points[index1]*m_localScaling;
|
||||
int index0 = i%m_unscaledPoints.size();
|
||||
int index1 = (i+1)%m_unscaledPoints.size();
|
||||
pa = getScaledPoint(index0);
|
||||
pb = getScaledPoint(index1);
|
||||
}
|
||||
|
||||
void btConvexHullShape::getVertex(int i,btPoint3& vtx) const
|
||||
void btConvexHullShape::getVertex(int i,btVector3& vtx) const
|
||||
{
|
||||
vtx = m_points[i]*m_localScaling;
|
||||
vtx = getScaledPoint(i);
|
||||
}
|
||||
|
||||
int btConvexHullShape::getNumPlanes() const
|
||||
@ -171,16 +172,16 @@ int btConvexHullShape::getNumPlanes() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
void btConvexHullShape::getPlane(btVector3& ,btPoint3& ,int ) const
|
||||
void btConvexHullShape::getPlane(btVector3& ,btVector3& ,int ) const
|
||||
{
|
||||
|
||||
btAssert(0);
|
||||
}
|
||||
|
||||
//not yet
|
||||
bool btConvexHullShape::isInside(const btPoint3& ,btScalar ) const
|
||||
bool btConvexHullShape::isInside(const btVector3& ,btScalar ) const
|
||||
{
|
||||
assert(0);
|
||||
btAssert(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ subject to the following restrictions:
|
||||
///Bullet provides a general and fast collision detector for convex shapes based on GJK and EPA using localGetSupportingVertex.
|
||||
ATTRIBUTE_ALIGNED16(class) btConvexHullShape : public btPolyhedralConvexShape
|
||||
{
|
||||
btAlignedObjectArray<btPoint3> m_points;
|
||||
btAlignedObjectArray<btVector3> m_unscaledPoints;
|
||||
|
||||
public:
|
||||
BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
@ -33,23 +33,38 @@ public:
|
||||
///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.
|
||||
///It is easier to not pass any points in the constructor, and just add one point at a time, using addPoint.
|
||||
///btConvexHullShape make an internal copy of the points.
|
||||
btConvexHullShape(const btScalar* points=0,int numPoints=0, int stride=sizeof(btPoint3));
|
||||
btConvexHullShape(const btScalar* points=0,int numPoints=0, int stride=sizeof(btVector3));
|
||||
|
||||
void addPoint(const btPoint3& point);
|
||||
void addPoint(const btVector3& point);
|
||||
|
||||
btPoint3* getPoints()
|
||||
|
||||
btVector3* getUnscaledPoints()
|
||||
{
|
||||
return &m_points[0];
|
||||
return &m_unscaledPoints[0];
|
||||
}
|
||||
|
||||
const btPoint3* getPoints() const
|
||||
const btVector3* getUnscaledPoints() const
|
||||
{
|
||||
return &m_points[0];
|
||||
return &m_unscaledPoints[0];
|
||||
}
|
||||
|
||||
int getNumPoints() const
|
||||
///getPoints is obsolete, please use getUnscaledPoints
|
||||
const btVector3* getPoints() const
|
||||
{
|
||||
return m_points.size();
|
||||
return getUnscaledPoints();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btVector3 getScaledPoint(int i) const
|
||||
{
|
||||
return m_unscaledPoints[i] * m_localScaling;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE int getNumPoints() const
|
||||
{
|
||||
return m_unscaledPoints.size();
|
||||
}
|
||||
|
||||
virtual btVector3 localGetSupportingVertex(const btVector3& vec)const;
|
||||
@ -57,7 +72,6 @@ public:
|
||||
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
|
||||
|
||||
|
||||
virtual int getShapeType()const { return CONVEX_HULL_SHAPE_PROXYTYPE; }
|
||||
|
||||
//debugging
|
||||
virtual const char* getName()const {return "Convex";}
|
||||
@ -65,11 +79,11 @@ public:
|
||||
|
||||
virtual int getNumVertices() const;
|
||||
virtual int getNumEdges() const;
|
||||
virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const;
|
||||
virtual void getVertex(int i,btPoint3& vtx) const;
|
||||
virtual void getEdge(int i,btVector3& pa,btVector3& pb) const;
|
||||
virtual void getVertex(int i,btVector3& vtx) const;
|
||||
virtual int getNumPlanes() const;
|
||||
virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const;
|
||||
virtual bool isInside(const btPoint3& pt,btScalar tolerance) const;
|
||||
virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const;
|
||||
virtual bool isInside(const btVector3& pt,btScalar tolerance) const;
|
||||
|
||||
///in case we receive negative scaling
|
||||
virtual void setLocalScaling(const btVector3& scaling);
|
||||
|
@ -17,6 +17,7 @@ subject to the following restrictions:
|
||||
#include "btConvexInternalShape.h"
|
||||
|
||||
|
||||
|
||||
btConvexInternalShape::btConvexInternalShape()
|
||||
: m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),
|
||||
m_collisionMargin(CONVEX_DISTANCE_MARGIN)
|
||||
@ -48,7 +49,8 @@ void btConvexInternalShape::getAabbSlow(const btTransform& trans,btVector3&minAa
|
||||
tmp = trans(localGetSupportingVertex(vec*trans.getBasis()));
|
||||
minAabb[i] = tmp[i]-margin;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
btVector3 btConvexInternalShape::localGetSupportingVertex(const btVector3& vec)const
|
||||
@ -70,6 +72,7 @@ btVector3 btConvexInternalShape::localGetSupportingVertex(const btVector3& vec)c
|
||||
return supVertex;
|
||||
|
||||
#else
|
||||
btAssert(0);
|
||||
return btVector3(0,0,0);
|
||||
#endif //__SPU__
|
||||
|
||||
|
@ -19,23 +19,18 @@ class btConvexInternalShape : public btConvexShape
|
||||
|
||||
btScalar m_padding;
|
||||
|
||||
btConvexInternalShape();
|
||||
|
||||
public:
|
||||
|
||||
btConvexInternalShape();
|
||||
|
||||
|
||||
virtual ~btConvexInternalShape()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
virtual btVector3 localGetSupportingVertex(const btVector3& vec)const;
|
||||
#ifndef __SPU__
|
||||
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const= 0;
|
||||
|
||||
//notice that the vectors should be unit length
|
||||
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0;
|
||||
#endif //#ifndef __SPU__
|
||||
|
||||
const btVector3& getImplicitShapeDimensions() const
|
||||
{
|
||||
|
156
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp
vendored
Normal file
156
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
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 "btConvexPointCloudShape.h"
|
||||
#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
|
||||
|
||||
#include "LinearMath/btQuaternion.h"
|
||||
|
||||
void btConvexPointCloudShape::setLocalScaling(const btVector3& scaling)
|
||||
{
|
||||
m_localScaling = scaling;
|
||||
recalcLocalAabb();
|
||||
}
|
||||
|
||||
#ifndef __SPU__
|
||||
btVector3 btConvexPointCloudShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
|
||||
{
|
||||
btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
|
||||
btScalar newDot,maxDot = btScalar(-1e30);
|
||||
|
||||
btVector3 vec = vec0;
|
||||
btScalar lenSqr = vec.length2();
|
||||
if (lenSqr < btScalar(0.0001))
|
||||
{
|
||||
vec.setValue(1,0,0);
|
||||
} else
|
||||
{
|
||||
btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
|
||||
vec *= rlen;
|
||||
}
|
||||
|
||||
|
||||
for (int i=0;i<m_numPoints;i++)
|
||||
{
|
||||
btVector3 vtx = getScaledPoint(i);
|
||||
|
||||
newDot = vec.dot(vtx);
|
||||
if (newDot > maxDot)
|
||||
{
|
||||
maxDot = newDot;
|
||||
supVec = vtx;
|
||||
}
|
||||
}
|
||||
return supVec;
|
||||
}
|
||||
|
||||
void btConvexPointCloudShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
|
||||
{
|
||||
btScalar newDot;
|
||||
//use 'w' component of supportVerticesOut?
|
||||
{
|
||||
for (int i=0;i<numVectors;i++)
|
||||
{
|
||||
supportVerticesOut[i][3] = btScalar(-1e30);
|
||||
}
|
||||
}
|
||||
for (int i=0;i<m_numPoints;i++)
|
||||
{
|
||||
btVector3 vtx = getScaledPoint(i);
|
||||
|
||||
for (int j=0;j<numVectors;j++)
|
||||
{
|
||||
const btVector3& vec = vectors[j];
|
||||
|
||||
newDot = vec.dot(vtx);
|
||||
if (newDot > supportVerticesOut[j][3])
|
||||
{
|
||||
//WARNING: don't swap next lines, the w component would get overwritten!
|
||||
supportVerticesOut[j] = vtx;
|
||||
supportVerticesOut[j][3] = newDot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
btVector3 btConvexPointCloudShape::localGetSupportingVertex(const btVector3& vec)const
|
||||
{
|
||||
btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec);
|
||||
|
||||
if ( getMargin()!=btScalar(0.) )
|
||||
{
|
||||
btVector3 vecnorm = vec;
|
||||
if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
|
||||
{
|
||||
vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
|
||||
}
|
||||
vecnorm.normalize();
|
||||
supVertex+= getMargin() * vecnorm;
|
||||
}
|
||||
return supVertex;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//currently just for debugging (drawing), perhaps future support for algebraic continuous collision detection
|
||||
//Please note that you can debug-draw btConvexHullShape with the Raytracer Demo
|
||||
int btConvexPointCloudShape::getNumVertices() const
|
||||
{
|
||||
return m_numPoints;
|
||||
}
|
||||
|
||||
int btConvexPointCloudShape::getNumEdges() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void btConvexPointCloudShape::getEdge(int i,btVector3& pa,btVector3& pb) const
|
||||
{
|
||||
btAssert (0);
|
||||
}
|
||||
|
||||
void btConvexPointCloudShape::getVertex(int i,btVector3& vtx) const
|
||||
{
|
||||
vtx = m_unscaledPoints[i]*m_localScaling;
|
||||
}
|
||||
|
||||
int btConvexPointCloudShape::getNumPlanes() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void btConvexPointCloudShape::getPlane(btVector3& ,btVector3& ,int ) const
|
||||
{
|
||||
|
||||
btAssert(0);
|
||||
}
|
||||
|
||||
//not yet
|
||||
bool btConvexPointCloudShape::isInside(const btVector3& ,btScalar ) const
|
||||
{
|
||||
btAssert(0);
|
||||
return false;
|
||||
}
|
||||
|
96
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.h
vendored
Normal file
96
extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.h
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
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_CONVEX_POINT_CLOUD_SHAPE_H
|
||||
#define BT_CONVEX_POINT_CLOUD_SHAPE_H
|
||||
|
||||
#include "btPolyhedralConvexShape.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
///The btConvexPointCloudShape implements an implicit convex hull of an array of vertices.
|
||||
ATTRIBUTE_ALIGNED16(class) btConvexPointCloudShape : public btPolyhedralConvexShape
|
||||
{
|
||||
btVector3* m_unscaledPoints;
|
||||
int m_numPoints;
|
||||
|
||||
public:
|
||||
BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
btConvexPointCloudShape(btVector3* points,int numPoints, const btVector3& localScaling,bool computeAabb = true)
|
||||
{
|
||||
m_localScaling = localScaling;
|
||||
m_shapeType = CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE;
|
||||
m_unscaledPoints = points;
|
||||
m_numPoints = numPoints;
|
||||
|
||||
if (computeAabb)
|
||||
recalcLocalAabb();
|
||||
}
|
||||
|
||||
void setPoints (btVector3* points, int numPoints, bool computeAabb = true)
|
||||
{
|
||||
m_unscaledPoints = points;
|
||||
m_numPoints = numPoints;
|
||||
|
||||
if (computeAabb)
|
||||
recalcLocalAabb();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btVector3* getUnscaledPoints()
|
||||
{
|
||||
return m_unscaledPoints;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE const btVector3* getUnscaledPoints() const
|
||||
{
|
||||
return m_unscaledPoints;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE int getNumPoints() const
|
||||
{
|
||||
return m_numPoints;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btVector3 getScaledPoint( int index) const
|
||||
{
|
||||
return m_unscaledPoints[index] * m_localScaling;
|
||||
}
|
||||
|
||||
#ifndef __SPU__
|
||||
virtual btVector3 localGetSupportingVertex(const btVector3& vec)const;
|
||||
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
|
||||
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
|
||||
#endif
|
||||
|
||||
|
||||
//debugging
|
||||
virtual const char* getName()const {return "ConvexPointCloud";}
|
||||
|
||||
virtual int getNumVertices() const;
|
||||
virtual int getNumEdges() const;
|
||||
virtual void getEdge(int i,btVector3& pa,btVector3& pb) const;
|
||||
virtual void getVertex(int i,btVector3& vtx) const;
|
||||
virtual int getNumPlanes() const;
|
||||
virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const;
|
||||
virtual bool isInside(const btVector3& pt,btScalar tolerance) const;
|
||||
|
||||
///in case we receive negative scaling
|
||||
virtual void setLocalScaling(const btVector3& scaling);
|
||||
};
|
||||
|
||||
|
||||
#endif //BT_CONVEX_POINT_CLOUD_SHAPE_H
|
||||
|
@ -14,5 +14,366 @@ subject to the following restrictions:
|
||||
*/
|
||||
|
||||
#include "btConvexShape.h"
|
||||
#include "btTriangleShape.h"
|
||||
#include "btSphereShape.h"
|
||||
#include "btCylinderShape.h"
|
||||
#include "btCapsuleShape.h"
|
||||
#include "btConvexHullShape.h"
|
||||
#include "btConvexPointCloudShape.h"
|
||||
|
||||
btConvexShape::btConvexShape ()
|
||||
{
|
||||
}
|
||||
|
||||
btConvexShape::~btConvexShape()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static btVector3 convexHullSupport (const btVector3& localDir, const btVector3* points, int numPoints, const btVector3& localScaling)
|
||||
{
|
||||
btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
|
||||
btScalar newDot,maxDot = btScalar(-1e30);
|
||||
|
||||
btVector3 vec0(localDir.getX(),localDir.getY(),localDir.getZ());
|
||||
btVector3 vec = vec0;
|
||||
btScalar lenSqr = vec.length2();
|
||||
if (lenSqr < btScalar(0.0001))
|
||||
{
|
||||
vec.setValue(1,0,0);
|
||||
} else {
|
||||
btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
|
||||
vec *= rlen;
|
||||
}
|
||||
|
||||
|
||||
for (int i=0;i<numPoints;i++)
|
||||
{
|
||||
btVector3 vtx = points[i] * localScaling;
|
||||
|
||||
newDot = vec.dot(vtx);
|
||||
if (newDot > maxDot)
|
||||
{
|
||||
maxDot = newDot;
|
||||
supVec = vtx;
|
||||
}
|
||||
}
|
||||
return btVector3(supVec.getX(),supVec.getY(),supVec.getZ());
|
||||
}
|
||||
|
||||
btVector3 btConvexShape::localGetSupportVertexWithoutMarginNonVirtual (const btVector3& localDir) const
|
||||
{
|
||||
switch (m_shapeType)
|
||||
{
|
||||
case SPHERE_SHAPE_PROXYTYPE:
|
||||
{
|
||||
return btVector3(0,0,0);
|
||||
}
|
||||
case BOX_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btBoxShape* convexShape = (btBoxShape*)this;
|
||||
const btVector3& halfExtents = convexShape->getImplicitShapeDimensions();
|
||||
|
||||
return btVector3(btFsels(localDir.x(), halfExtents.x(), -halfExtents.x()),
|
||||
btFsels(localDir.y(), halfExtents.y(), -halfExtents.y()),
|
||||
btFsels(localDir.z(), halfExtents.z(), -halfExtents.z()));
|
||||
}
|
||||
case TRIANGLE_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btTriangleShape* triangleShape = (btTriangleShape*)this;
|
||||
btVector3 dir(localDir.getX(),localDir.getY(),localDir.getZ());
|
||||
btVector3* vertices = &triangleShape->m_vertices1[0];
|
||||
btVector3 dots(dir.dot(vertices[0]), dir.dot(vertices[1]), dir.dot(vertices[2]));
|
||||
btVector3 sup = vertices[dots.maxAxis()];
|
||||
return btVector3(sup.getX(),sup.getY(),sup.getZ());
|
||||
}
|
||||
case CYLINDER_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btCylinderShape* cylShape = (btCylinderShape*)this;
|
||||
//mapping of halfextents/dimension onto radius/height depends on how cylinder local orientation is (upAxis)
|
||||
|
||||
btVector3 halfExtents = cylShape->getImplicitShapeDimensions();
|
||||
btVector3 v(localDir.getX(),localDir.getY(),localDir.getZ());
|
||||
int cylinderUpAxis = cylShape->getUpAxis();
|
||||
int XX(1),YY(0),ZZ(2);
|
||||
|
||||
switch (cylinderUpAxis)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
XX = 1;
|
||||
YY = 0;
|
||||
ZZ = 2;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
XX = 0;
|
||||
YY = 1;
|
||||
ZZ = 2;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
XX = 0;
|
||||
YY = 2;
|
||||
ZZ = 1;
|
||||
|
||||
}
|
||||
break;
|
||||
default:
|
||||
btAssert(0);
|
||||
break;
|
||||
};
|
||||
|
||||
btScalar radius = halfExtents[XX];
|
||||
btScalar halfHeight = halfExtents[cylinderUpAxis];
|
||||
|
||||
btVector3 tmp;
|
||||
btScalar d ;
|
||||
|
||||
btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
|
||||
if (s != btScalar(0.0))
|
||||
{
|
||||
d = radius / s;
|
||||
tmp[XX] = v[XX] * d;
|
||||
tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
|
||||
tmp[ZZ] = v[ZZ] * d;
|
||||
return btVector3(tmp.getX(),tmp.getY(),tmp.getZ());
|
||||
} else {
|
||||
tmp[XX] = radius;
|
||||
tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
|
||||
tmp[ZZ] = btScalar(0.0);
|
||||
return btVector3(tmp.getX(),tmp.getY(),tmp.getZ());
|
||||
}
|
||||
}
|
||||
case CAPSULE_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btVector3 vec0(localDir.getX(),localDir.getY(),localDir.getZ());
|
||||
|
||||
btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
|
||||
btScalar halfHeight = capsuleShape->getHalfHeight();
|
||||
int capsuleUpAxis = capsuleShape->getUpAxis();
|
||||
|
||||
btScalar radius = capsuleShape->getRadius();
|
||||
btVector3 supVec(0,0,0);
|
||||
|
||||
btScalar maxDot(btScalar(-1e30));
|
||||
|
||||
btVector3 vec = vec0;
|
||||
btScalar lenSqr = vec.length2();
|
||||
if (lenSqr < btScalar(0.0001))
|
||||
{
|
||||
vec.setValue(1,0,0);
|
||||
} else
|
||||
{
|
||||
btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
|
||||
vec *= rlen;
|
||||
}
|
||||
btVector3 vtx;
|
||||
btScalar newDot;
|
||||
{
|
||||
btVector3 pos(0,0,0);
|
||||
pos[capsuleUpAxis] = halfHeight;
|
||||
|
||||
//vtx = pos +vec*(radius);
|
||||
vtx = pos +vec*capsuleShape->getLocalScalingNV()*(radius) - vec * capsuleShape->getMarginNV();
|
||||
newDot = vec.dot(vtx);
|
||||
|
||||
|
||||
if (newDot > maxDot)
|
||||
{
|
||||
maxDot = newDot;
|
||||
supVec = vtx;
|
||||
}
|
||||
}
|
||||
{
|
||||
btVector3 pos(0,0,0);
|
||||
pos[capsuleUpAxis] = -halfHeight;
|
||||
|
||||
//vtx = pos +vec*(radius);
|
||||
vtx = pos +vec*capsuleShape->getLocalScalingNV()*(radius) - vec * capsuleShape->getMarginNV();
|
||||
newDot = vec.dot(vtx);
|
||||
if (newDot > maxDot)
|
||||
{
|
||||
maxDot = newDot;
|
||||
supVec = vtx;
|
||||
}
|
||||
}
|
||||
return btVector3(supVec.getX(),supVec.getY(),supVec.getZ());
|
||||
}
|
||||
case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btConvexPointCloudShape* convexPointCloudShape = (btConvexPointCloudShape*)this;
|
||||
btVector3* points = convexPointCloudShape->getUnscaledPoints ();
|
||||
int numPoints = convexPointCloudShape->getNumPoints ();
|
||||
return convexHullSupport (localDir, points, numPoints,convexPointCloudShape->getLocalScalingNV());
|
||||
}
|
||||
case CONVEX_HULL_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btConvexHullShape* convexHullShape = (btConvexHullShape*)this;
|
||||
btVector3* points = convexHullShape->getUnscaledPoints();
|
||||
int numPoints = convexHullShape->getNumPoints ();
|
||||
return convexHullSupport (localDir, points, numPoints,convexHullShape->getLocalScalingNV());
|
||||
}
|
||||
default:
|
||||
#ifndef __SPU__
|
||||
return this->localGetSupportingVertexWithoutMargin (localDir);
|
||||
#else
|
||||
btAssert (0);
|
||||
#endif
|
||||
}
|
||||
|
||||
// should never reach here
|
||||
btAssert (0);
|
||||
return btVector3 (btScalar(0.0f), btScalar(0.0f), btScalar(0.0f));
|
||||
}
|
||||
|
||||
btVector3 btConvexShape::localGetSupportVertexNonVirtual (const btVector3& localDir) const
|
||||
{
|
||||
btVector3 localDirNorm = localDir;
|
||||
if (localDirNorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
|
||||
{
|
||||
localDirNorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
|
||||
}
|
||||
localDirNorm.normalize ();
|
||||
|
||||
return localGetSupportVertexWithoutMarginNonVirtual(localDirNorm)+ getMarginNonVirtual() * localDirNorm;
|
||||
}
|
||||
|
||||
/* TODO: This should be bumped up to btCollisionShape () */
|
||||
btScalar btConvexShape::getMarginNonVirtual () const
|
||||
{
|
||||
switch (m_shapeType)
|
||||
{
|
||||
case SPHERE_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btSphereShape* sphereShape = (btSphereShape*)this;
|
||||
return sphereShape->getRadius ();
|
||||
}
|
||||
case BOX_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btBoxShape* convexShape = (btBoxShape*)this;
|
||||
return convexShape->getMarginNV ();
|
||||
}
|
||||
case TRIANGLE_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btTriangleShape* triangleShape = (btTriangleShape*)this;
|
||||
return triangleShape->getMarginNV ();
|
||||
}
|
||||
case CYLINDER_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btCylinderShape* cylShape = (btCylinderShape*)this;
|
||||
return cylShape->getMarginNV();
|
||||
}
|
||||
case CAPSULE_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
|
||||
return capsuleShape->getMarginNV();
|
||||
}
|
||||
case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
|
||||
/* fall through */
|
||||
case CONVEX_HULL_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btPolyhedralConvexShape* convexHullShape = (btPolyhedralConvexShape*)this;
|
||||
return convexHullShape->getMarginNV();
|
||||
}
|
||||
default:
|
||||
#ifndef __SPU__
|
||||
return this->getMargin ();
|
||||
#else
|
||||
btAssert (0);
|
||||
#endif
|
||||
}
|
||||
|
||||
// should never reach here
|
||||
btAssert (0);
|
||||
return btScalar(0.0f);
|
||||
}
|
||||
|
||||
void btConvexShape::getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
|
||||
{
|
||||
switch (m_shapeType)
|
||||
{
|
||||
case SPHERE_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btSphereShape* sphereShape = (btSphereShape*)this;
|
||||
btScalar radius = sphereShape->getImplicitShapeDimensions().getX();// * convexShape->getLocalScaling().getX();
|
||||
btScalar margin = radius + sphereShape->getMarginNonVirtual();
|
||||
const btVector3& center = t.getOrigin();
|
||||
btVector3 extent(margin,margin,margin);
|
||||
aabbMin = center - extent;
|
||||
aabbMax = center + extent;
|
||||
}
|
||||
break;
|
||||
case CYLINDER_SHAPE_PROXYTYPE:
|
||||
/* fall through */
|
||||
case BOX_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btBoxShape* convexShape = (btBoxShape*)this;
|
||||
btScalar margin=convexShape->getMarginNonVirtual();
|
||||
btVector3 halfExtents = convexShape->getImplicitShapeDimensions();
|
||||
halfExtents += btVector3(margin,margin,margin);
|
||||
btMatrix3x3 abs_b = t.getBasis().absolute();
|
||||
btVector3 center = t.getOrigin();
|
||||
btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));
|
||||
|
||||
aabbMin = center - extent;
|
||||
aabbMax = center + extent;
|
||||
break;
|
||||
}
|
||||
case TRIANGLE_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btTriangleShape* triangleShape = (btTriangleShape*)this;
|
||||
btScalar margin = triangleShape->getMarginNonVirtual();
|
||||
for (int i=0;i<3;i++)
|
||||
{
|
||||
btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
|
||||
vec[i] = btScalar(1.);
|
||||
|
||||
btVector3 sv = localGetSupportVertexWithoutMarginNonVirtual(vec*t.getBasis());
|
||||
|
||||
btVector3 tmp = t(sv);
|
||||
aabbMax[i] = tmp[i]+margin;
|
||||
vec[i] = btScalar(-1.);
|
||||
tmp = t(localGetSupportVertexWithoutMarginNonVirtual(vec*t.getBasis()));
|
||||
aabbMin[i] = tmp[i]-margin;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CAPSULE_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
|
||||
btVector3 halfExtents(capsuleShape->getRadius(),capsuleShape->getRadius(),capsuleShape->getRadius());
|
||||
int m_upAxis = capsuleShape->getUpAxis();
|
||||
halfExtents[m_upAxis] = capsuleShape->getRadius() + capsuleShape->getHalfHeight();
|
||||
halfExtents += btVector3(capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual());
|
||||
btMatrix3x3 abs_b = t.getBasis().absolute();
|
||||
btVector3 center = t.getOrigin();
|
||||
btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));
|
||||
aabbMin = center - extent;
|
||||
aabbMax = center + extent;
|
||||
}
|
||||
break;
|
||||
case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
|
||||
case CONVEX_HULL_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btPolyhedralConvexShape* convexHullShape = (btPolyhedralConvexShape*)this;
|
||||
btScalar margin = convexHullShape->getMarginNonVirtual();
|
||||
convexHullShape->getNonvirtualAabb (t, aabbMin, aabbMax, margin);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
#ifndef __SPU__
|
||||
this->getAabb (t, aabbMin, aabbMax);
|
||||
#else
|
||||
btAssert (0);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
// should never reach here
|
||||
btAssert (0);
|
||||
}
|
||||
|
@ -24,8 +24,6 @@ subject to the following restrictions:
|
||||
#include "btCollisionMargin.h"
|
||||
#include "LinearMath/btAlignedAllocator.h"
|
||||
|
||||
//todo: get rid of this btConvexCastResult thing!
|
||||
struct btConvexCastResult;
|
||||
#define MAX_PREFERRED_PENETRATION_DIRECTIONS 10
|
||||
|
||||
/// The btConvexShape is an abstract shape interface, implemented by all convex shapes such as btBoxShape, btConvexHullShape etc.
|
||||
@ -38,20 +36,25 @@ public:
|
||||
|
||||
BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
virtual ~btConvexShape()
|
||||
{
|
||||
btConvexShape ();
|
||||
|
||||
}
|
||||
virtual ~btConvexShape();
|
||||
|
||||
virtual btVector3 localGetSupportingVertex(const btVector3& vec)const = 0;
|
||||
|
||||
////////
|
||||
#ifndef __SPU__
|
||||
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const=0;
|
||||
#endif //#ifndef __SPU__
|
||||
|
||||
btVector3 localGetSupportVertexWithoutMarginNonVirtual (const btVector3& vec) const;
|
||||
btVector3 localGetSupportVertexNonVirtual (const btVector3& vec) const;
|
||||
btScalar getMarginNonVirtual () const;
|
||||
void getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const;
|
||||
|
||||
virtual btVector3 localGetSupportingVertex(const btVector3& vec)const =0;
|
||||
#ifndef __SPU__
|
||||
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const= 0;
|
||||
|
||||
//notice that the vectors should be unit length
|
||||
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0;
|
||||
#endif //#ifndef __SPU__
|
||||
|
||||
|
||||
///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
|
||||
void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const =0;
|
||||
@ -69,6 +72,9 @@ public:
|
||||
|
||||
virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const=0;
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -20,8 +20,9 @@ subject to the following restrictions:
|
||||
|
||||
|
||||
btConvexTriangleMeshShape ::btConvexTriangleMeshShape (btStridingMeshInterface* meshInterface, bool calcAabb)
|
||||
:m_stridingMesh(meshInterface)
|
||||
: btPolyhedralConvexShape(), m_stridingMesh(meshInterface)
|
||||
{
|
||||
m_shapeType = CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE;
|
||||
if ( calcAabb )
|
||||
recalcLocalAabb();
|
||||
}
|
||||
@ -107,7 +108,7 @@ void btConvexTriangleMeshShape::batchedUnitVectorGetSupportingVertexWithoutMargi
|
||||
}
|
||||
}
|
||||
|
||||
//todo: could do the batch inside the callback!
|
||||
///@todo: could do the batch inside the callback!
|
||||
|
||||
|
||||
for (int j=0;j<numVectors;j++)
|
||||
@ -162,12 +163,12 @@ int btConvexTriangleMeshShape::getNumEdges() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
void btConvexTriangleMeshShape::getEdge(int ,btPoint3& ,btPoint3& ) const
|
||||
void btConvexTriangleMeshShape::getEdge(int ,btVector3& ,btVector3& ) const
|
||||
{
|
||||
btAssert(0);
|
||||
}
|
||||
|
||||
void btConvexTriangleMeshShape::getVertex(int ,btPoint3& ) const
|
||||
void btConvexTriangleMeshShape::getVertex(int ,btVector3& ) const
|
||||
{
|
||||
btAssert(0);
|
||||
}
|
||||
@ -177,13 +178,13 @@ int btConvexTriangleMeshShape::getNumPlanes() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
void btConvexTriangleMeshShape::getPlane(btVector3& ,btPoint3& ,int ) const
|
||||
void btConvexTriangleMeshShape::getPlane(btVector3& ,btVector3& ,int ) const
|
||||
{
|
||||
btAssert(0);
|
||||
}
|
||||
|
||||
//not yet
|
||||
bool btConvexTriangleMeshShape::isInside(const btPoint3& ,btScalar ) const
|
||||
bool btConvexTriangleMeshShape::isInside(const btVector3& ,btScalar ) const
|
||||
{
|
||||
btAssert(0);
|
||||
return false;
|
||||
@ -268,15 +269,12 @@ void btConvexTriangleMeshShape::calculatePrincipalAxisTransform(btTransform& pri
|
||||
btVector3 a = triangle[0] - center;
|
||||
btVector3 b = triangle[1] - center;
|
||||
btVector3 c = triangle[2] - center;
|
||||
btVector3 abc = a + b + c;
|
||||
btScalar volNeg = -btFabs(a.triple(b, c)) * btScalar(1. / 6);
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
for (int k = 0; k <= j; k++)
|
||||
{
|
||||
i[j][k] = i[k][j] = volNeg * (center[j] * center[k]
|
||||
+ btScalar(0.25) * (center[j] * abc[k] + center[k] * abc[j])
|
||||
+ btScalar(0.1) * (a[j] * a[k] + b[j] * b[k] + c[j] * c[k])
|
||||
i[j][k] = i[k][j] = volNeg * (btScalar(0.1) * (a[j] * a[k] + b[j] * b[k] + c[j] * c[k])
|
||||
+ btScalar(0.05) * (a[j] * b[k] + a[k] * b[j] + a[j] * c[k] + a[k] * c[j] + b[j] * c[k] + b[k] * c[j]));
|
||||
}
|
||||
}
|
||||
|
@ -29,18 +29,16 @@ public:
|
||||
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
|
||||
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
|
||||
|
||||
virtual int getShapeType()const { return CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE; }
|
||||
|
||||
//debugging
|
||||
virtual const char* getName()const {return "ConvexTrimesh";}
|
||||
|
||||
virtual int getNumVertices() const;
|
||||
virtual int getNumEdges() const;
|
||||
virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const;
|
||||
virtual void getVertex(int i,btPoint3& vtx) const;
|
||||
virtual void getEdge(int i,btVector3& pa,btVector3& pb) const;
|
||||
virtual void getVertex(int i,btVector3& vtx) const;
|
||||
virtual int getNumPlanes() const;
|
||||
virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const;
|
||||
virtual bool isInside(const btPoint3& pt,btScalar tolerance) const;
|
||||
virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const;
|
||||
virtual bool isInside(const btVector3& pt,btScalar tolerance) const;
|
||||
|
||||
|
||||
virtual void setLocalScaling(const btVector3& scaling);
|
||||
|
@ -13,12 +13,12 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "btCylinderShape.h"
|
||||
#include "LinearMath/btPoint3.h"
|
||||
|
||||
btCylinderShape::btCylinderShape (const btVector3& halfExtents)
|
||||
:btBoxShape(halfExtents),
|
||||
m_upAxis(1)
|
||||
{
|
||||
m_shapeType = CYLINDER_SHAPE_PROXYTYPE;
|
||||
recalcLocalAabb();
|
||||
}
|
||||
|
||||
|
@ -62,11 +62,7 @@ public:
|
||||
//use box inertia
|
||||
// virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
|
||||
|
||||
virtual int getShapeType() const
|
||||
{
|
||||
return CYLINDER_SHAPE_PROXYTYPE;
|
||||
}
|
||||
|
||||
|
||||
int getUpAxis() const
|
||||
{
|
||||
return m_upAxis;
|
||||
|
@ -19,8 +19,9 @@ subject to the following restrictions:
|
||||
#include "btCollisionShape.h"
|
||||
|
||||
|
||||
btEmptyShape::btEmptyShape()
|
||||
btEmptyShape::btEmptyShape() : btConcaveShape ()
|
||||
{
|
||||
m_shapeType = EMPTY_SHAPE_PROXYTYPE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,14 +51,14 @@ public:
|
||||
|
||||
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
|
||||
|
||||
virtual int getShapeType() const { return EMPTY_SHAPE_PROXYTYPE;}
|
||||
|
||||
|
||||
virtual const char* getName()const
|
||||
{
|
||||
return "Empty";
|
||||
}
|
||||
|
||||
virtual void processAllTriangles(btTriangleCallback* ,const btVector3& ,const btVector3& ) const
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
btVector3 m_localScaling;
|
||||
|
@ -18,71 +18,107 @@ subject to the following restrictions:
|
||||
#include "LinearMath/btTransformUtil.h"
|
||||
|
||||
|
||||
btHeightfieldTerrainShape::btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength,void* heightfieldData,btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges)
|
||||
: m_heightStickWidth(heightStickWidth),
|
||||
m_heightStickLength(heightStickLength),
|
||||
m_maxHeight(maxHeight),
|
||||
m_width((btScalar)heightStickWidth-1),
|
||||
m_length((btScalar)heightStickLength-1),
|
||||
m_heightfieldDataUnknown(heightfieldData),
|
||||
m_useFloatData(useFloatData),
|
||||
m_flipQuadEdges(flipQuadEdges),
|
||||
m_useDiamondSubdivision(false),
|
||||
m_upAxis(upAxis),
|
||||
m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.))
|
||||
|
||||
btHeightfieldTerrainShape::btHeightfieldTerrainShape
|
||||
(
|
||||
int heightStickWidth, int heightStickLength, void* heightfieldData,
|
||||
btScalar heightScale, btScalar minHeight, btScalar maxHeight,int upAxis,
|
||||
PHY_ScalarType hdt, bool flipQuadEdges
|
||||
)
|
||||
{
|
||||
initialize(heightStickWidth, heightStickLength, heightfieldData,
|
||||
heightScale, minHeight, maxHeight, upAxis, hdt,
|
||||
flipQuadEdges);
|
||||
}
|
||||
|
||||
|
||||
btScalar quantizationMargin = 1.f;
|
||||
|
||||
//enlarge the AABB to avoid division by zero when initializing the quantization values
|
||||
btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin);
|
||||
btHeightfieldTerrainShape::btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength,void* heightfieldData,btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges)
|
||||
{
|
||||
// legacy constructor: support only float or unsigned char,
|
||||
// and min height is zero
|
||||
PHY_ScalarType hdt = (useFloatData) ? PHY_FLOAT : PHY_UCHAR;
|
||||
btScalar minHeight = 0.0;
|
||||
|
||||
btVector3 halfExtents(0,0,0);
|
||||
// previously, height = uchar * maxHeight / 65535.
|
||||
// So to preserve legacy behavior, heightScale = maxHeight / 65535
|
||||
btScalar heightScale = maxHeight / 65535;
|
||||
|
||||
initialize(heightStickWidth, heightStickLength, heightfieldData,
|
||||
heightScale, minHeight, maxHeight, upAxis, hdt,
|
||||
flipQuadEdges);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void btHeightfieldTerrainShape::initialize
|
||||
(
|
||||
int heightStickWidth, int heightStickLength, void* heightfieldData,
|
||||
btScalar heightScale, btScalar minHeight, btScalar maxHeight, int upAxis,
|
||||
PHY_ScalarType hdt, bool flipQuadEdges
|
||||
)
|
||||
{
|
||||
// validation
|
||||
btAssert(heightStickWidth > 1 && "bad width");
|
||||
btAssert(heightStickLength > 1 && "bad length");
|
||||
btAssert(heightfieldData && "null heightfield data");
|
||||
// btAssert(heightScale) -- do we care? Trust caller here
|
||||
btAssert(minHeight <= maxHeight && "bad min/max height");
|
||||
btAssert(upAxis >= 0 && upAxis < 3 &&
|
||||
"bad upAxis--should be in range [0,2]");
|
||||
btAssert(hdt != PHY_UCHAR || hdt != PHY_FLOAT || hdt != PHY_SHORT &&
|
||||
"Bad height data type enum");
|
||||
|
||||
// initialize member variables
|
||||
m_shapeType = TERRAIN_SHAPE_PROXYTYPE;
|
||||
m_heightStickWidth = heightStickWidth;
|
||||
m_heightStickLength = heightStickLength;
|
||||
m_minHeight = minHeight;
|
||||
m_maxHeight = maxHeight;
|
||||
m_width = (btScalar) (heightStickWidth - 1);
|
||||
m_length = (btScalar) (heightStickLength - 1);
|
||||
m_heightScale = heightScale;
|
||||
m_heightfieldDataUnknown = heightfieldData;
|
||||
m_heightDataType = hdt;
|
||||
m_flipQuadEdges = flipQuadEdges;
|
||||
m_useDiamondSubdivision = false;
|
||||
m_upAxis = upAxis;
|
||||
m_localScaling.setValue(btScalar(1.), btScalar(1.), btScalar(1.));
|
||||
|
||||
// determine min/max axis-aligned bounding box (aabb) values
|
||||
switch (m_upAxis)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
halfExtents.setValue(
|
||||
btScalar(m_maxHeight),
|
||||
btScalar(m_width), //?? don't know if this should change
|
||||
btScalar(m_length));
|
||||
m_localAabbMin.setValue(m_minHeight, 0, 0);
|
||||
m_localAabbMax.setValue(m_maxHeight, m_width, m_length);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
halfExtents.setValue(
|
||||
btScalar(m_width),
|
||||
btScalar(m_maxHeight),
|
||||
btScalar(m_length));
|
||||
m_localAabbMin.setValue(0, m_minHeight, 0);
|
||||
m_localAabbMax.setValue(m_width, m_maxHeight, m_length);
|
||||
break;
|
||||
};
|
||||
case 2:
|
||||
{
|
||||
halfExtents.setValue(
|
||||
btScalar(m_width),
|
||||
btScalar(m_length),
|
||||
btScalar(m_maxHeight)
|
||||
);
|
||||
m_localAabbMin.setValue(0, 0, m_minHeight);
|
||||
m_localAabbMax.setValue(m_width, m_length, m_maxHeight);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
//need to get valid m_upAxis
|
||||
btAssert(0);
|
||||
btAssert(0 && "Bad m_upAxis");
|
||||
}
|
||||
}
|
||||
|
||||
halfExtents*= btScalar(0.5);
|
||||
|
||||
m_localAabbMin = -halfExtents - clampValue;
|
||||
m_localAabbMax = halfExtents + clampValue;
|
||||
btVector3 aabbSize = m_localAabbMax - m_localAabbMin;
|
||||
|
||||
// remember origin (defined as exact middle of aabb)
|
||||
m_localOrigin = btScalar(0.5) * (m_localAabbMin + m_localAabbMax);
|
||||
}
|
||||
|
||||
|
||||
|
||||
btHeightfieldTerrainShape::~btHeightfieldTerrainShape()
|
||||
{
|
||||
}
|
||||
@ -92,57 +128,80 @@ btHeightfieldTerrainShape::~btHeightfieldTerrainShape()
|
||||
void btHeightfieldTerrainShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
|
||||
{
|
||||
btVector3 halfExtents = (m_localAabbMax-m_localAabbMin)* m_localScaling * btScalar(0.5);
|
||||
halfExtents += btVector3(getMargin(),getMargin(),getMargin());
|
||||
|
||||
btVector3 localOrigin(0, 0, 0);
|
||||
localOrigin[m_upAxis] = (m_minHeight + m_maxHeight) * btScalar(0.5);
|
||||
localOrigin *= m_localScaling;
|
||||
|
||||
btMatrix3x3 abs_b = t.getBasis().absolute();
|
||||
btPoint3 center = t.getOrigin();
|
||||
btVector3 center = t.getOrigin();
|
||||
btVector3 extent = btVector3(abs_b[0].dot(halfExtents),
|
||||
abs_b[1].dot(halfExtents),
|
||||
abs_b[2].dot(halfExtents));
|
||||
|
||||
extent += btVector3(getMargin(),getMargin(),getMargin());
|
||||
|
||||
aabbMin = center - extent;
|
||||
aabbMax = center + extent;
|
||||
|
||||
|
||||
}
|
||||
|
||||
btScalar btHeightfieldTerrainShape::getHeightFieldValue(int x,int y) const
|
||||
|
||||
/// This returns the "raw" (user's initial) height, not the actual height.
|
||||
/// The actual height needs to be adjusted to be relative to the center
|
||||
/// of the heightfield's AABB.
|
||||
btScalar
|
||||
btHeightfieldTerrainShape::getRawHeightFieldValue(int x,int y) const
|
||||
{
|
||||
btScalar val = 0.f;
|
||||
if (m_useFloatData)
|
||||
switch (m_heightDataType)
|
||||
{
|
||||
val = m_heightfieldDataFloat[(y*m_heightStickWidth)+x];
|
||||
} else
|
||||
{
|
||||
//assume unsigned short int
|
||||
unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y*m_heightStickWidth)+x];
|
||||
val = heightFieldValue* (m_maxHeight/btScalar(65535));
|
||||
case PHY_FLOAT:
|
||||
{
|
||||
val = m_heightfieldDataFloat[(y*m_heightStickWidth)+x];
|
||||
break;
|
||||
}
|
||||
|
||||
case PHY_UCHAR:
|
||||
{
|
||||
unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y*m_heightStickWidth)+x];
|
||||
val = heightFieldValue * m_heightScale;
|
||||
break;
|
||||
}
|
||||
|
||||
case PHY_SHORT:
|
||||
{
|
||||
short hfValue = m_heightfieldDataShort[(y * m_heightStickWidth) + x];
|
||||
val = hfValue * m_heightScale;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
btAssert(!"Bad m_heightDataType");
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// this returns the vertex in bullet-local coordinates
|
||||
void btHeightfieldTerrainShape::getVertex(int x,int y,btVector3& vertex) const
|
||||
{
|
||||
|
||||
btAssert(x>=0);
|
||||
btAssert(y>=0);
|
||||
btAssert(x<m_heightStickWidth);
|
||||
btAssert(y<m_heightStickLength);
|
||||
|
||||
|
||||
btScalar height = getHeightFieldValue(x,y);
|
||||
btScalar height = getRawHeightFieldValue(x,y);
|
||||
|
||||
switch (m_upAxis)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
vertex.setValue(
|
||||
height,
|
||||
height - m_localOrigin.getX(),
|
||||
(-m_width/btScalar(2.0)) + x,
|
||||
(-m_length/btScalar(2.0) ) + y
|
||||
);
|
||||
@ -152,7 +211,7 @@ void btHeightfieldTerrainShape::getVertex(int x,int y,btVector3& vertex) const
|
||||
{
|
||||
vertex.setValue(
|
||||
(-m_width/btScalar(2.0)) + x,
|
||||
height,
|
||||
height - m_localOrigin.getY(),
|
||||
(-m_length/btScalar(2.0)) + y
|
||||
);
|
||||
break;
|
||||
@ -162,7 +221,7 @@ void btHeightfieldTerrainShape::getVertex(int x,int y,btVector3& vertex) const
|
||||
vertex.setValue(
|
||||
(-m_width/btScalar(2.0)) + x,
|
||||
(-m_length/btScalar(2.0)) + y,
|
||||
height
|
||||
height - m_localOrigin.getZ()
|
||||
);
|
||||
break;
|
||||
}
|
||||
@ -174,45 +233,76 @@ void btHeightfieldTerrainShape::getVertex(int x,int y,btVector3& vertex) const
|
||||
}
|
||||
|
||||
vertex*=m_localScaling;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline int
|
||||
getQuantized
|
||||
(
|
||||
btScalar x
|
||||
)
|
||||
{
|
||||
if (x < 0.0) {
|
||||
return (int) (x - 0.5);
|
||||
}
|
||||
return (int) (x + 0.5);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// given input vector, return quantized version
|
||||
/**
|
||||
This routine is basically determining the gridpoint indices for a given
|
||||
input vector, answering the question: "which gridpoint is closest to the
|
||||
provided point?".
|
||||
|
||||
"with clamp" means that we restrict the point to be in the heightfield's
|
||||
axis-aligned bounding box.
|
||||
*/
|
||||
void btHeightfieldTerrainShape::quantizeWithClamp(int* out, const btVector3& point,int /*isMax*/) const
|
||||
{
|
||||
btVector3 clampedPoint(point);
|
||||
clampedPoint.setMax(m_localAabbMin);
|
||||
clampedPoint.setMin(m_localAabbMax);
|
||||
|
||||
btVector3 v = (clampedPoint);// - m_bvhAabbMin) * m_bvhQuantization;
|
||||
|
||||
//TODO: optimization: check out how to removed this btFabs
|
||||
out[0] = getQuantized(clampedPoint.getX());
|
||||
out[1] = getQuantized(clampedPoint.getY());
|
||||
out[2] = getQuantized(clampedPoint.getZ());
|
||||
|
||||
out[0] = (int)(v.getX() + v.getX() / btFabs(v.getX())* btScalar(0.5) );
|
||||
out[1] = (int)(v.getY() + v.getY() / btFabs(v.getY())* btScalar(0.5) );
|
||||
out[2] = (int)(v.getZ() + v.getZ() / btFabs(v.getZ())* btScalar(0.5) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// process all triangles within the provided axis-aligned bounding box
|
||||
/**
|
||||
basic algorithm:
|
||||
- convert input aabb to local coordinates (scale down and shift for local origin)
|
||||
- convert input aabb to a range of heightfield grid points (quantize)
|
||||
- iterate over all triangles in that subset of the grid
|
||||
*/
|
||||
void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
|
||||
{
|
||||
(void)callback;
|
||||
(void)aabbMax;
|
||||
(void)aabbMin;
|
||||
|
||||
//quantize the aabbMin and aabbMax, and adjust the start/end ranges
|
||||
|
||||
int quantizedAabbMin[3];
|
||||
int quantizedAabbMax[3];
|
||||
|
||||
// scale down the input aabb's so they are in local (non-scaled) coordinates
|
||||
btVector3 localAabbMin = aabbMin*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
|
||||
btVector3 localAabbMax = aabbMax*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
|
||||
|
||||
|
||||
// account for local origin
|
||||
localAabbMin += m_localOrigin;
|
||||
localAabbMax += m_localOrigin;
|
||||
|
||||
//quantize the aabbMin and aabbMax, and adjust the start/end ranges
|
||||
int quantizedAabbMin[3];
|
||||
int quantizedAabbMax[3];
|
||||
quantizeWithClamp(quantizedAabbMin, localAabbMin,0);
|
||||
quantizeWithClamp(quantizedAabbMax, localAabbMax,1);
|
||||
|
||||
|
||||
// expand the min/max quantized values
|
||||
// this is to catch the case where the input aabb falls between grid points!
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
quantizedAabbMin[i]--;
|
||||
quantizedAabbMax[i]++;
|
||||
}
|
||||
|
||||
int startX=0;
|
||||
int endX=m_heightStickWidth-1;
|
||||
@ -223,11 +313,6 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
quantizedAabbMin[1]+=m_heightStickWidth/2-1;
|
||||
quantizedAabbMax[1]+=m_heightStickWidth/2+1;
|
||||
quantizedAabbMin[2]+=m_heightStickLength/2-1;
|
||||
quantizedAabbMax[2]+=m_heightStickLength/2+1;
|
||||
|
||||
if (quantizedAabbMin[1]>startX)
|
||||
startX = quantizedAabbMin[1];
|
||||
if (quantizedAabbMax[1]<endX)
|
||||
@ -240,11 +325,6 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
quantizedAabbMin[0]+=m_heightStickWidth/2-1;
|
||||
quantizedAabbMax[0]+=m_heightStickWidth/2+1;
|
||||
quantizedAabbMin[2]+=m_heightStickLength/2-1;
|
||||
quantizedAabbMax[2]+=m_heightStickLength/2+1;
|
||||
|
||||
if (quantizedAabbMin[0]>startX)
|
||||
startX = quantizedAabbMin[0];
|
||||
if (quantizedAabbMax[0]<endX)
|
||||
@ -257,11 +337,6 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback
|
||||
};
|
||||
case 2:
|
||||
{
|
||||
quantizedAabbMin[0]+=m_heightStickWidth/2-1;
|
||||
quantizedAabbMax[0]+=m_heightStickWidth/2+1;
|
||||
quantizedAabbMin[1]+=m_heightStickLength/2-1;
|
||||
quantizedAabbMax[1]+=m_heightStickLength/2+1;
|
||||
|
||||
if (quantizedAabbMin[0]>startX)
|
||||
startX = quantizedAabbMin[0];
|
||||
if (quantizedAabbMax[0]<endX)
|
||||
|
@ -18,28 +18,80 @@ subject to the following restrictions:
|
||||
|
||||
#include "btConcaveShape.h"
|
||||
|
||||
///The btHeightfieldTerrainShape simulates a 2D heightfield terrain collision shape. You can also use the more general btBvhTriangleMeshShape instead.
|
||||
///An example implementation of btHeightfieldTerrainShape is provided in Demos/VehicleDemo/VehicleDemo.cpp
|
||||
///btHeightfieldTerrainShape simulates a 2D heightfield terrain
|
||||
/**
|
||||
The caller is responsible for maintaining the heightfield array; this
|
||||
class does not make a copy.
|
||||
|
||||
The heightfield can be dynamic so long as the min/max height values
|
||||
capture the extremes (heights must always be in that range).
|
||||
|
||||
The local origin of the heightfield is assumed to be the exact
|
||||
center (as determined by width and length and height, with each
|
||||
axis multiplied by the localScaling).
|
||||
|
||||
\b NOTE: be careful with coordinates. If you have a heightfield with a local
|
||||
min height of -100m, and a max height of +500m, you may be tempted to place it
|
||||
at the origin (0,0) and expect the heights in world coordinates to be
|
||||
-100 to +500 meters.
|
||||
Actually, the heights will be -300 to +300m, because bullet will re-center
|
||||
the heightfield based on its AABB (which is determined by the min/max
|
||||
heights). So keep in mind that once you create a btHeightfieldTerrainShape
|
||||
object, the heights will be adjusted relative to the center of the AABB. This
|
||||
is different to the behavior of many rendering engines, but is useful for
|
||||
physics engines.
|
||||
|
||||
Most (but not all) rendering and heightfield libraries assume upAxis = 1
|
||||
(that is, the y-axis is "up"). This class allows any of the 3 coordinates
|
||||
to be "up". Make sure your choice of axis is consistent with your rendering
|
||||
system.
|
||||
|
||||
The heightfield heights are determined from the data type used for the
|
||||
heightfieldData array.
|
||||
|
||||
- PHY_UCHAR: height at a point is the uchar value at the
|
||||
grid point, multipled by heightScale. uchar isn't recommended
|
||||
because of its inability to deal with negative values, and
|
||||
low resolution (8-bit).
|
||||
|
||||
- PHY_SHORT: height at a point is the short int value at that grid
|
||||
point, multipled by heightScale.
|
||||
|
||||
- PHY_FLOAT: height at a point is the float value at that grid
|
||||
point. heightScale is ignored when using the float heightfield
|
||||
data type.
|
||||
|
||||
Whatever the caller specifies as minHeight and maxHeight will be honored.
|
||||
The class will not inspect the heightfield to discover the actual minimum
|
||||
or maximum heights. These values are used to determine the heightfield's
|
||||
axis-aligned bounding box, multiplied by localScaling.
|
||||
|
||||
For usage and testing see the TerrainDemo.
|
||||
*/
|
||||
class btHeightfieldTerrainShape : public btConcaveShape
|
||||
{
|
||||
protected:
|
||||
btVector3 m_localAabbMin;
|
||||
btVector3 m_localAabbMax;
|
||||
|
||||
btVector3 m_localOrigin;
|
||||
|
||||
///terrain data
|
||||
int m_heightStickWidth;
|
||||
int m_heightStickLength;
|
||||
btScalar m_minHeight;
|
||||
btScalar m_maxHeight;
|
||||
btScalar m_width;
|
||||
btScalar m_length;
|
||||
btScalar m_heightScale;
|
||||
union
|
||||
{
|
||||
unsigned char* m_heightfieldDataUnsignedChar;
|
||||
short* m_heightfieldDataShort;
|
||||
btScalar* m_heightfieldDataFloat;
|
||||
void* m_heightfieldDataUnknown;
|
||||
};
|
||||
|
||||
bool m_useFloatData;
|
||||
|
||||
PHY_ScalarType m_heightDataType;
|
||||
bool m_flipQuadEdges;
|
||||
bool m_useDiamondSubdivision;
|
||||
|
||||
@ -47,31 +99,49 @@ protected:
|
||||
|
||||
btVector3 m_localScaling;
|
||||
|
||||
virtual btScalar getHeightFieldValue(int x,int y) const;
|
||||
virtual btScalar getRawHeightFieldValue(int x,int y) const;
|
||||
void quantizeWithClamp(int* out, const btVector3& point,int isMax) const;
|
||||
void getVertex(int x,int y,btVector3& vertex) const;
|
||||
|
||||
inline bool testQuantizedAabbAgainstQuantizedAabb(int* aabbMin1, int* aabbMax1,const int* aabbMin2,const int* aabbMax2) const
|
||||
{
|
||||
bool overlap = true;
|
||||
overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
|
||||
overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
|
||||
overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
|
||||
return overlap;
|
||||
}
|
||||
|
||||
|
||||
/// protected initialization
|
||||
/**
|
||||
Handles the work of constructors so that public constructors can be
|
||||
backwards-compatible without a lot of copy/paste.
|
||||
*/
|
||||
void initialize(int heightStickWidth, int heightStickLength,
|
||||
void* heightfieldData, btScalar heightScale,
|
||||
btScalar minHeight, btScalar maxHeight, int upAxis,
|
||||
PHY_ScalarType heightDataType, bool flipQuadEdges);
|
||||
|
||||
public:
|
||||
btHeightfieldTerrainShape(int heightStickWidth,int heightStickHeight,void* heightfieldData, btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges);
|
||||
/// preferred constructor
|
||||
/**
|
||||
This constructor supports a range of heightfield
|
||||
data types, and allows for a non-zero minimum height value.
|
||||
heightScale is needed for any integer-based heightfield data types.
|
||||
*/
|
||||
btHeightfieldTerrainShape(int heightStickWidth,int heightStickLength,
|
||||
void* heightfieldData, btScalar heightScale,
|
||||
btScalar minHeight, btScalar maxHeight,
|
||||
int upAxis, PHY_ScalarType heightDataType,
|
||||
bool flipQuadEdges);
|
||||
|
||||
/// legacy constructor
|
||||
/**
|
||||
The legacy constructor assumes the heightfield has a minimum height
|
||||
of zero. Only unsigned char or floats are supported. For legacy
|
||||
compatibility reasons, heightScale is calculated as maxHeight / 65535
|
||||
(and is only used when useFloatData = false).
|
||||
*/
|
||||
btHeightfieldTerrainShape(int heightStickWidth,int heightStickLength,void* heightfieldData, btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges);
|
||||
|
||||
virtual ~btHeightfieldTerrainShape();
|
||||
|
||||
|
||||
void setUseDiamondSubdivision(bool useDiamondSubdivision=true) { m_useDiamondSubdivision = useDiamondSubdivision;}
|
||||
|
||||
virtual int getShapeType() const
|
||||
{
|
||||
return TERRAIN_SHAPE_PROXYTYPE;
|
||||
}
|
||||
|
||||
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
|
||||
|
||||
|
@ -17,23 +17,25 @@ subject to the following restrictions:
|
||||
|
||||
|
||||
btMinkowskiSumShape::btMinkowskiSumShape(const btConvexShape* shapeA,const btConvexShape* shapeB)
|
||||
:m_shapeA(shapeA),
|
||||
: btConvexInternalShape (),
|
||||
m_shapeA(shapeA),
|
||||
m_shapeB(shapeB)
|
||||
{
|
||||
m_shapeType = MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE;
|
||||
m_transA.setIdentity();
|
||||
m_transB.setIdentity();
|
||||
}
|
||||
|
||||
btVector3 btMinkowskiSumShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
|
||||
{
|
||||
btVector3 supVertexA = m_transA(m_shapeA->localGetSupportingVertexWithoutMargin(-vec*m_transA.getBasis()));
|
||||
btVector3 supVertexB = m_transB(m_shapeB->localGetSupportingVertexWithoutMargin(vec*m_transB.getBasis()));
|
||||
btVector3 supVertexA = m_transA(m_shapeA->localGetSupportingVertexWithoutMargin(vec*m_transA.getBasis()));
|
||||
btVector3 supVertexB = m_transB(m_shapeB->localGetSupportingVertexWithoutMargin(-vec*m_transB.getBasis()));
|
||||
return supVertexA - supVertexB;
|
||||
}
|
||||
|
||||
void btMinkowskiSumShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
|
||||
{
|
||||
//todo: could make recursive use of batching. probably this shape is not used frequently.
|
||||
///@todo: could make recursive use of batching. probably this shape is not used frequently.
|
||||
for (int i=0;i<numVectors;i++)
|
||||
{
|
||||
supportVerticesOut[i] = localGetSupportingVertexWithoutMargin(vectors[i]);
|
||||
|
@ -46,8 +46,6 @@ public:
|
||||
const btTransform& GetTransformB()const { return m_transB;}
|
||||
|
||||
|
||||
virtual int getShapeType() const { return MINKOWSKI_SUM_SHAPE_PROXYTYPE; }
|
||||
|
||||
virtual btScalar getMargin() const;
|
||||
|
||||
const btConvexShape* getShapeA() const { return m_shapeA;}
|
||||
|
@ -18,8 +18,9 @@ subject to the following restrictions:
|
||||
#include "LinearMath/btQuaternion.h"
|
||||
|
||||
btMultiSphereShape::btMultiSphereShape (const btVector3& inertiaHalfExtents,const btVector3* positions,const btScalar* radi,int numSpheres)
|
||||
:m_inertiaHalfExtents(inertiaHalfExtents)
|
||||
:btConvexInternalShape (), m_inertiaHalfExtents(inertiaHalfExtents)
|
||||
{
|
||||
m_shapeType = MULTI_SPHERE_SHAPE_PROXYTYPE;
|
||||
btScalar startMargin = btScalar(1e30);
|
||||
|
||||
m_numSpheres = numSpheres;
|
||||
|
@ -62,7 +62,6 @@ public:
|
||||
return m_radi[index];
|
||||
}
|
||||
|
||||
virtual int getShapeType() const { return MULTI_SPHERE_SHAPE_PROXYTYPE; }
|
||||
|
||||
virtual const char* getName()const
|
||||
{
|
||||
|
@ -31,10 +31,12 @@ public:
|
||||
|
||||
BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
btMultimaterialTriangleMeshShape(): btBvhTriangleMeshShape() {}
|
||||
btMultimaterialTriangleMeshShape(): btBvhTriangleMeshShape() {m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE;}
|
||||
btMultimaterialTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true):
|
||||
btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression, buildBvh)
|
||||
{
|
||||
m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE;
|
||||
|
||||
btVector3 m_triangle[3];
|
||||
const unsigned char *vertexbase;
|
||||
int numverts;
|
||||
@ -67,6 +69,8 @@ public:
|
||||
btMultimaterialTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax, bool buildBvh = true):
|
||||
btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression, bvhAabbMin, bvhAabbMax, buildBvh)
|
||||
{
|
||||
m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE;
|
||||
|
||||
btVector3 m_triangle[3];
|
||||
const unsigned char *vertexbase;
|
||||
int numverts;
|
||||
@ -107,11 +111,6 @@ public:
|
||||
m_materialLookup = NULL;
|
||||
*/
|
||||
}
|
||||
virtual int getShapeType() const
|
||||
{
|
||||
return MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE;
|
||||
}
|
||||
|
||||
//debugging
|
||||
virtual const char* getName()const {return "MULTIMATERIALTRIANGLEMESH";}
|
||||
|
||||
|
@ -319,19 +319,19 @@ void btOptimizedBvh::updateBvhNodes(btStridingMeshInterface* meshInterface,int f
|
||||
{
|
||||
|
||||
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
|
||||
btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
|
||||
#ifdef DEBUG_PATCH_COLORS
|
||||
btVector3 mycolor = color[index&3];
|
||||
graphicsbase[8] = mycolor.getX();
|
||||
graphicsbase[9] = mycolor.getY();
|
||||
graphicsbase[10] = mycolor.getZ();
|
||||
#endif //DEBUG_PATCH_COLORS
|
||||
|
||||
|
||||
triangleVerts[j] = btVector3(
|
||||
graphicsbase[0]*meshScaling.getX(),
|
||||
graphicsbase[1]*meshScaling.getY(),
|
||||
graphicsbase[2]*meshScaling.getZ());
|
||||
if (type == PHY_FLOAT)
|
||||
{
|
||||
float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
|
||||
triangleVerts[j] = btVector3(
|
||||
graphicsbase[0]*meshScaling.getX(),
|
||||
graphicsbase[1]*meshScaling.getY(),
|
||||
graphicsbase[2]*meshScaling.getZ());
|
||||
}
|
||||
else
|
||||
{
|
||||
double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
|
||||
triangleVerts[j] = btVector3( btScalar(graphicsbase[0]*meshScaling.getX()), btScalar(graphicsbase[1]*meshScaling.getY()), btScalar(graphicsbase[2]*meshScaling.getZ()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -15,8 +15,8 @@ subject to the following restrictions:
|
||||
|
||||
#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
|
||||
|
||||
btPolyhedralConvexShape::btPolyhedralConvexShape()
|
||||
:m_localAabbMin(1,1,1),
|
||||
btPolyhedralConvexShape::btPolyhedralConvexShape() :btConvexInternalShape(),
|
||||
m_localAabbMin(1,1,1),
|
||||
m_localAabbMax(-1,-1,-1),
|
||||
m_isLocalAabbValid(false),
|
||||
m_optionalHull(0)
|
||||
@ -25,7 +25,6 @@ m_optionalHull(0)
|
||||
}
|
||||
|
||||
|
||||
|
||||
btVector3 btPolyhedralConvexShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
|
||||
{
|
||||
int i;
|
||||
|
@ -16,7 +16,6 @@ subject to the following restrictions:
|
||||
#ifndef BU_SHAPE
|
||||
#define BU_SHAPE
|
||||
|
||||
#include "LinearMath/btPoint3.h"
|
||||
#include "LinearMath/btMatrix3x3.h"
|
||||
#include "LinearMath/btAabbUtil2.h"
|
||||
#include "btConvexInternalShape.h"
|
||||
@ -36,12 +35,28 @@ public:
|
||||
btPolyhedralConvexShape();
|
||||
|
||||
//brute force implementations
|
||||
|
||||
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
|
||||
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
|
||||
|
||||
|
||||
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
|
||||
|
||||
|
||||
void setCachedLocalAabb (const btVector3& aabbMin, const btVector3& aabbMax)
|
||||
{
|
||||
m_isLocalAabbValid = true;
|
||||
m_localAabbMin = aabbMin;
|
||||
m_localAabbMax = aabbMax;
|
||||
}
|
||||
|
||||
inline void getCachedLocalAabb (btVector3& aabbMin, btVector3& aabbMax) const
|
||||
{
|
||||
btAssert(m_isLocalAabbValid);
|
||||
aabbMin = m_localAabbMin;
|
||||
aabbMax = m_localAabbMax;
|
||||
}
|
||||
|
||||
inline void getNonvirtualAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax, btScalar margin) const
|
||||
{
|
||||
|
||||
@ -59,13 +74,13 @@ public:
|
||||
|
||||
virtual int getNumVertices() const = 0 ;
|
||||
virtual int getNumEdges() const = 0;
|
||||
virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const = 0;
|
||||
virtual void getVertex(int i,btPoint3& vtx) const = 0;
|
||||
virtual void getEdge(int i,btVector3& pa,btVector3& pb) const = 0;
|
||||
virtual void getVertex(int i,btVector3& vtx) const = 0;
|
||||
virtual int getNumPlanes() const = 0;
|
||||
virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const = 0;
|
||||
virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const = 0;
|
||||
// virtual int getIndex(int i) const = 0 ;
|
||||
|
||||
virtual bool isInside(const btPoint3& pt,btScalar tolerance) const = 0;
|
||||
virtual bool isInside(const btVector3& pt,btScalar tolerance) const = 0;
|
||||
|
||||
/// optional Hull is for optional Separating Axis Test Hull collision detection, see Hull.cpp
|
||||
class Hull* m_optionalHull;
|
||||
|
@ -15,11 +15,10 @@ subject to the following restrictions:
|
||||
|
||||
#include "btScaledBvhTriangleMeshShape.h"
|
||||
|
||||
btScaledBvhTriangleMeshShape::btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,btVector3 localScaling)
|
||||
:m_bvhTriMeshShape(childShape),
|
||||
m_localScaling(localScaling)
|
||||
btScaledBvhTriangleMeshShape::btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,const btVector3& localScaling)
|
||||
:m_localScaling(localScaling),m_bvhTriMeshShape(childShape)
|
||||
{
|
||||
|
||||
m_shapeType = SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE;
|
||||
}
|
||||
|
||||
btScaledBvhTriangleMeshShape::~btScaledBvhTriangleMeshShape()
|
||||
@ -35,7 +34,7 @@ class btScaledTriangleCallback : public btTriangleCallback
|
||||
|
||||
public:
|
||||
|
||||
btScaledTriangleCallback(btTriangleCallback* originalCallback,btVector3 localScaling)
|
||||
btScaledTriangleCallback(btTriangleCallback* originalCallback,const btVector3& localScaling)
|
||||
:m_originalCallback(originalCallback),
|
||||
m_localScaling(localScaling)
|
||||
{
|
||||
@ -94,7 +93,7 @@ void btScaledBvhTriangleMeshShape::getAabb(const btTransform& trans,btVector3& a
|
||||
|
||||
btMatrix3x3 abs_b = trans.getBasis().absolute();
|
||||
|
||||
btPoint3 center = trans(localCenter);
|
||||
btVector3 center = trans(localCenter);
|
||||
|
||||
btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
|
||||
abs_b[1].dot(localHalfExtents),
|
||||
|
@ -32,15 +32,10 @@ ATTRIBUTE_ALIGNED16(class) btScaledBvhTriangleMeshShape : public btConcaveShape
|
||||
public:
|
||||
|
||||
|
||||
btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,btVector3 localScaling);
|
||||
btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,const btVector3& localScaling);
|
||||
|
||||
virtual ~btScaledBvhTriangleMeshShape();
|
||||
|
||||
virtual int getShapeType() const
|
||||
{
|
||||
//use un-used 'FAST_CONCAVE_MESH_PROXYTYPE' for now, later add SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE to btBroadphaseProxy.h
|
||||
return SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE;
|
||||
}
|
||||
|
||||
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
|
||||
virtual void setLocalScaling(const btVector3& scaling);
|
||||
|
@ -18,12 +18,6 @@ subject to the following restrictions:
|
||||
|
||||
#include "LinearMath/btQuaternion.h"
|
||||
|
||||
|
||||
btSphereShape ::btSphereShape (btScalar radius)
|
||||
{
|
||||
m_implicitShapeDimensions.setX(radius);
|
||||
}
|
||||
|
||||
btVector3 btSphereShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
|
||||
{
|
||||
(void)vec;
|
||||
|
@ -27,8 +27,12 @@ ATTRIBUTE_ALIGNED16(class) btSphereShape : public btConvexInternalShape
|
||||
public:
|
||||
BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
btSphereShape (btScalar radius);
|
||||
|
||||
btSphereShape (btScalar radius) : btConvexInternalShape ()
|
||||
{
|
||||
m_shapeType = SPHERE_SHAPE_PROXYTYPE;
|
||||
m_implicitShapeDimensions.setX(radius);
|
||||
m_collisionMargin = radius;
|
||||
}
|
||||
|
||||
virtual btVector3 localGetSupportingVertex(const btVector3& vec)const;
|
||||
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
|
||||
@ -40,7 +44,6 @@ public:
|
||||
|
||||
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
|
||||
|
||||
virtual int getShapeType() const { return SPHERE_SHAPE_PROXYTYPE; }
|
||||
|
||||
btScalar getRadius() const { return m_implicitShapeDimensions.getX() * m_localScaling.getX();}
|
||||
|
||||
|
@ -19,10 +19,11 @@ subject to the following restrictions:
|
||||
|
||||
|
||||
btStaticPlaneShape::btStaticPlaneShape(const btVector3& planeNormal,btScalar planeConstant)
|
||||
:m_planeNormal(planeNormal.normalized()),
|
||||
: btConcaveShape (), m_planeNormal(planeNormal.normalized()),
|
||||
m_planeConstant(planeConstant),
|
||||
m_localScaling(btScalar(0.),btScalar(0.),btScalar(0.))
|
||||
{
|
||||
m_shapeType = STATIC_PLANE_PROXYTYPE;
|
||||
// btAssert( btFuzzyZero(m_planeNormal.length() - btScalar(1.)) );
|
||||
}
|
||||
|
||||
|
@ -36,11 +36,6 @@ public:
|
||||
virtual ~btStaticPlaneShape();
|
||||
|
||||
|
||||
virtual int getShapeType() const
|
||||
{
|
||||
return STATIC_PLANE_PROXYTYPE;
|
||||
}
|
||||
|
||||
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
|
||||
|
||||
virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
|
||||
|
@ -18,16 +18,9 @@ subject to the following restrictions:
|
||||
|
||||
#include "LinearMath/btVector3.h"
|
||||
#include "btTriangleCallback.h"
|
||||
#include "btConcaveShape.h"
|
||||
|
||||
|
||||
/// PHY_ScalarType enumerates possible scalar types.
|
||||
/// See the btStridingMeshInterface for its use
|
||||
typedef enum PHY_ScalarType {
|
||||
PHY_FLOAT,
|
||||
PHY_DOUBLE,
|
||||
PHY_INTEGER,
|
||||
PHY_SHORT,
|
||||
PHY_FIXEDPOINT88
|
||||
} PHY_ScalarType;
|
||||
|
||||
/// The btStridingMeshInterface is the interface class for high performance generic access to triangle meshes, used in combination with btBvhTriangleMeshShape and some other collision shapes.
|
||||
/// Using index striding of 3*sizeof(integer) it can use triangle arrays, using index striding of 1*sizeof(integer) it can handle triangle strips.
|
||||
@ -77,8 +70,16 @@ class btStridingMeshInterface
|
||||
virtual void preallocateIndices(int numindices)=0;
|
||||
|
||||
virtual bool hasPremadeAabb() const { return false; }
|
||||
virtual void setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const {}
|
||||
virtual void getPremadeAabb(btVector3* aabbMin, btVector3* aabbMax ) const {}
|
||||
virtual void setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const
|
||||
{
|
||||
(void) aabbMin;
|
||||
(void) aabbMax;
|
||||
}
|
||||
virtual void getPremadeAabb(btVector3* aabbMin, btVector3* aabbMax ) const
|
||||
{
|
||||
(void) aabbMin;
|
||||
(void) aabbMax;
|
||||
}
|
||||
|
||||
const btVector3& getScaling() const {
|
||||
return m_scaling;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user