25#if DBVT_BP_PROFILE||DBVT_BP_ENABLE_BENCHMARK
32 __forceinline ProfileScope(
btClock& clock,
unsigned long& value) :
33 m_clock(&clock),m_value(&value),m_base(clock.getTimeMicroseconds())
36 __forceinline ~ProfileScope()
38 (*m_value)+=m_clock->getTimeMicroseconds()-m_base;
41 unsigned long* m_value;
44#define SPC(_value_) ProfileScope spc_scope(m_clock,_value_)
59 if(list) list->links[0]=item;
67 if(item->links[0]) item->links[0]->links[1]=item->links[1];
else list=item->links[1];
68 if(item->links[1]) item->links[1]->links[0]=item->links[0];
76 while(root) { ++n;root=root->links[1]; }
82static inline void clear(T& value)
84 static const struct ZeroDummy : T {} zerodummy;
171 int collisionFilterGroup,
172 int collisionFilterMask,
176 collisionFilterGroup,
177 collisionFilterMask);
189 collider.
proxy=proxy;
313#if DBVT_BP_PREVENTFALSEUPDATE
317 bool docollide=
false;
332 if(delta[0]<0) velocity[0]=-velocity[0];
333 if(delta[1]<0) velocity[1]=-velocity[1];
334 if(delta[2]<0) velocity[2]=-velocity[2];
381 bool docollide=
false;
418 if(0==(
m_pid%DBVT_BP_PROFILING_RATE))
421 unsigned int total=m_profiling.m_total;
422 if(total<=0) total=1;
423 printf(
"ddcollide: %u%% (%uus)\r\n",(50+m_profiling.m_ddcollide*100)/total,m_profiling.m_ddcollide/DBVT_BP_PROFILING_RATE);
424 printf(
"fdcollide: %u%% (%uus)\r\n",(50+m_profiling.m_fdcollide*100)/total,m_profiling.m_fdcollide/DBVT_BP_PROFILING_RATE);
425 printf(
"cleanup: %u%% (%uus)\r\n",(50+m_profiling.m_cleanup*100)/total,m_profiling.m_cleanup/DBVT_BP_PROFILING_RATE);
426 printf(
"total: %uus\r\n",total/DBVT_BP_PROFILING_RATE);
427 const unsigned long sum=m_profiling.m_ddcollide+
428 m_profiling.m_fdcollide+
429 m_profiling.m_cleanup;
430 printf(
"leaked: %u%% (%uus)\r\n",100-((50+
sum*100)/total),(total-
sum)/DBVT_BP_PROFILING_RATE);
463 for (i=0;i<overlappingPairArray.
size();i++)
468 bool isDuplicate = (pair == previousPair);
472 bool needsRemoval =
false;
483 needsRemoval =
false;
509 overlappingPairArray.
resize(overlappingPairArray.
size() - invalidPair);
533 SPC(m_profiling.m_total);
547#if DBVT_BP_ACCURATESLEEPING
554#if DBVT_BP_ACCURATESLEEPING
556 collider.
proxy=current;
574 SPC(m_profiling.m_fdcollide);
579 SPC(m_profiling.m_ddcollide);
586 SPC(m_profiling.m_cleanup);
592 for(
int i=0;i<ni;++i)
695#if DBVT_BP_ENABLE_BENCHMARK
697struct btBroadphaseBenchmark
719 btSin(time)*amplitude/2;
721 btSin(time)*amplitude;
723 pbi->
setAabb(proxy,center-extents,center+extents,0);
726 static int UnsignedRand(
int range=RAND_MAX-1) {
return(rand()%(range+1)); }
728 static void OutputTime(
const char* name,
btClock& c,
unsigned count=0)
731 const unsigned long ms=(us+500)/1000;
734 printf(
"%s : %u us (%u ms), %.2f/s\r\n",name,us,ms,count/sec);
736 printf(
"%s : %u us (%u ms)\r\n",name,us,ms);
742 static const btBroadphaseBenchmark::Experiment experiments[]=
748 static const int nexperiments=
sizeof(experiments)/
sizeof(experiments[0]);
752 for(
int iexp=0;iexp<nexperiments;++iexp)
754 const btBroadphaseBenchmark::Experiment& experiment=experiments[iexp];
755 const int object_count=experiment.object_count;
756 const int update_count=(object_count*experiment.update_count)/100;
757 const int spawn_count=(object_count*experiment.spawn_count)/100;
758 const btScalar speed=experiment.speed;
759 const btScalar amplitude=experiment.amplitude;
760 printf(
"Experiment #%u '%s':\r\n",iexp,experiment.name);
761 printf(
"\tObjects: %u\r\n",object_count);
762 printf(
"\tUpdate: %u\r\n",update_count);
763 printf(
"\tSpawn: %u\r\n",spawn_count);
764 printf(
"\tSpeed: %f\r\n",speed);
765 printf(
"\tAmplitude: %f\r\n",amplitude);
770 for(
int i=0;i<object_count;++i)
772 btBroadphaseBenchmark::Object* po=
new btBroadphaseBenchmark::Object();
773 po->center[0]=btBroadphaseBenchmark::UnitRand()*50;
774 po->center[1]=btBroadphaseBenchmark::UnitRand()*50;
775 po->center[2]=btBroadphaseBenchmark::UnitRand()*50;
776 po->extents[0]=btBroadphaseBenchmark::UnitRand()*2+2;
777 po->extents[1]=btBroadphaseBenchmark::UnitRand()*2+2;
778 po->extents[2]=btBroadphaseBenchmark::UnitRand()*2+2;
779 po->time=btBroadphaseBenchmark::UnitRand()*2000;
780 po->proxy=pbi->
createProxy(po->center-po->extents,po->center+po->extents,0,po,1,1,0,0);
783 btBroadphaseBenchmark::OutputTime(
"\tInitialization",wallclock);
786 for(
int i=0;i<objects.
size();++i)
788 objects[i]->update(speed,amplitude,pbi);
790 btBroadphaseBenchmark::OutputTime(
"\tFirst update",wallclock);
793 for(
int i=0;i<experiment.iterations;++i)
795 for(
int j=0;j<update_count;++j)
797 objects[j]->update(speed,amplitude,pbi);
801 btBroadphaseBenchmark::OutputTime(
"\tUpdate",wallclock,experiment.iterations);
804 for(
int i=0;i<objects.
size();++i)
810 btBroadphaseBenchmark::OutputTime(
"\tRelease",wallclock);
#define btAlignedFree(ptr)
#define btAlignedAlloc(size, alignment)
static void clear(T &value)
#define SPC(_value_)
btDbvtBroadphase implementation by Nathanael Presson
static void listappend(T *item, T *&list)
static int listcount(T *root)
static void listremove(T *item, T *&list)
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
DBVT_INLINE bool Intersect(const btDbvtAabbMm &a, const btDbvtAabbMm &b)
DBVT_INLINE void Merge(const btDbvtAabbMm &a, const btDbvtAabbMm &b, btDbvtAabbMm &r)
DBVT_INLINE bool NotEqual(const btDbvtAabbMm &a, const btDbvtAabbMm &b)
const T & btMin(const T &a, const T &b)
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
#define ATTRIBUTE_ALIGNED16(a)
btScalar btSin(btScalar x)
btScalar btCos(btScalar x)
static T sum(const btAlignedObjectArray< T > &items)
unsigned int btGetCurrentThreadIndex()
const unsigned int BT_MAX_THREAD_COUNT
int size() const
return the number of elements in the array
void resize(int newsize, const T &fillData=T())
void quickSort(const L &CompareFunc)
void push_back(const T &_Val)
The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs.
virtual void calculateOverlappingPairs(btDispatcher *dispatcher)=0
calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during th...
virtual void setAabb(btBroadphaseProxy *proxy, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)=0
virtual void destroyProxy(btBroadphaseProxy *proxy, btDispatcher *dispatcher)=0
virtual btBroadphaseProxy * createProxy(const btVector3 &aabbMin, const btVector3 &aabbMax, int shapeType, void *userPtr, int collisionFilterGroup, int collisionFilterMask, btDispatcher *dispatcher)=0
The btClock is a portable basic clock that measures accurate time in seconds, use for profiling.
void reset()
Resets the initial reference time.
unsigned long long int getTimeMicroseconds()
Returns the time in us since the last call to reset or since the Clock was created.
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman,...
The btOverlappingPairCache provides an interface for overlapping pair management (add,...
virtual btBroadphasePairArray & getOverlappingPairArray()=0
virtual int getNumOverlappingPairs() const =0
virtual void cleanOverlappingPair(btBroadphasePair &pair, btDispatcher *dispatcher)=0
virtual ~btOverlappingPairCache()
virtual bool hasDeferredRemoval()=0
virtual void * removeOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1, btDispatcher *dispatcher)=0
virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy *proxy0, btDispatcher *dispatcher)=0
virtual btBroadphasePair * addOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)=0
btVector3 can be used to represent 3D points and vectors.
void Process(const btDbvtNode *leaf)
BroadphaseAabbTester(btBroadphaseAabbCallback &orgCallback)
btBroadphaseAabbCallback & m_aabbCallback
void Process(const btDbvtNode *leaf)
BroadphaseRayTester(btBroadphaseRayCallback &orgCallback)
btBroadphaseRayCallback & m_rayCallback
virtual bool process(const btBroadphaseProxy *proxy)=0
The btBroadphasePair class contains a pair of aabb-overlapping objects.
btBroadphaseProxy * m_pProxy1
btBroadphaseProxy * m_pProxy0
btCollisionAlgorithm * m_algorithm
The btBroadphaseProxy is the main class that can be used with the Bullet broadphases.
btVector3 m_rayDirectionInverse
added some cached data to accelerate ray-AABB tests
static btDbvtAabbMm FromMM(const btVector3 &mi, const btVector3 &mx)
DBVT_INLINE const btVector3 & Mins() const
static btDbvtAabbMm FromCR(const btVector3 &c, btScalar r)
DBVT_INLINE const btVector3 & Maxs() const
The btDbvtBroadphase implements a broadphase using two dynamic AABB bounding volume hierarchies/trees...
void performDeferredRemoval(btDispatcher *dispatcher)
virtual void calculateOverlappingPairs(btDispatcher *dispatcher)
calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during th...
static void benchmark(btBroadphaseInterface *)
virtual void destroyProxy(btBroadphaseProxy *proxy, btDispatcher *dispatcher)
virtual void getAabb(btBroadphaseProxy *proxy, btVector3 &aabbMin, btVector3 &aabbMax) const
void collide(btDispatcher *dispatcher)
btDbvtProxy * m_stageRoots[STAGECOUNT+1]
btBroadphaseProxy * createProxy(const btVector3 &aabbMin, const btVector3 &aabbMax, int shapeType, void *userPtr, int collisionFilterGroup, int collisionFilterMask, btDispatcher *dispatcher)
virtual void resetPool(btDispatcher *dispatcher)
reset broadphase internal structures, to ensure determinism/reproducability
void setAabbForceUpdate(btBroadphaseProxy *absproxy, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *)
this setAabbForceUpdate is similar to setAabb but always forces the aabb update.
btAlignedObjectArray< btAlignedObjectArray< const btDbvtNode * > > m_rayTestStacks
btDbvtBroadphase(btOverlappingPairCache *paircache=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))
virtual void aabbTest(const btVector3 &aabbMin, const btVector3 &aabbMax, btBroadphaseAabbCallback &callback)
virtual void printStats()
virtual void getBroadphaseAabb(btVector3 &aabbMin, btVector3 &aabbMax) const
getAabb returns the axis aligned bounding box in the 'global' coordinate frame will add some transfor...
btOverlappingPairCache * m_paircache
virtual void setAabb(btBroadphaseProxy *proxy, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)
virtual btOverlappingPairCache * getOverlappingPairCache()
btDbvtTreeCollider(btDbvtBroadphase *p)
void Process(const btDbvtNode *n)
void Process(const btDbvtNode *na, const btDbvtNode *nb)
btDbvtNode * insert(const btDbvtVolume &box, void *data)
void optimizeIncremental(int passes)
void optimizeTopDown(int bu_treshold=128)
void update(btDbvtNode *leaf, int lookahead=-1)
DBVT_PREFIX void collideTV(const btDbvtNode *root, const btDbvtVolume &volume, DBVT_IPOLICY) const
DBVT_PREFIX void rayTestInternal(const btDbvtNode *root, const btVector3 &rayFrom, const btVector3 &rayTo, const btVector3 &rayDirectionInverse, unsigned int signs[3], btScalar lambda_max, const btVector3 &aabbMin, const btVector3 &aabbMax, btAlignedObjectArray< const btDbvtNode * > &stack, DBVT_IPOLICY) const
rayTestInternal is faster than rayTest, because it uses a persistent stack (to reduce dynamic memory ...
DBVT_PREFIX void collideTTpersistentStack(const btDbvtNode *root0, const btDbvtNode *root1, DBVT_IPOLICY)
void remove(btDbvtNode *leaf)