25#if DBVT_BP_PROFILE || DBVT_BP_ENABLE_BENCHMARK
32 __forceinline ProfileScope(
btClock& clock,
unsigned long& value) : m_clock(&clock), m_value(&value), m_base(clock.getTimeMicroseconds())
35 __forceinline ~ProfileScope()
37 (*m_value) += m_clock->getTimeMicroseconds() - m_base;
40 unsigned long* m_value;
43#define SPC(_value_) ProfileScope spc_scope(m_clock, _value_)
57 item->links[1] = list;
58 if (list) list->links[0] = item;
67 item->links[0]->links[1] = item->links[1];
69 list = item->links[1];
70 if (item->links[1]) item->links[1]->links[0] = item->links[0];
81 root = root->links[1];
88static inline void clear(T& value)
90 static const struct ZeroDummy : T
179 int collisionFilterGroup,
180 int collisionFilterMask,
184 collisionFilterGroup,
185 collisionFilterMask);
197 collider.
proxy = proxy;
319#if DBVT_BP_PREVENTFALSEUPDATE
323 bool docollide =
false;
338 if (delta[0] < 0) velocity[0] = -velocity[0];
339 if (delta[1] < 0) velocity[1] = -velocity[1];
340 if (delta[2] < 0) velocity[2] = -velocity[2];
384 bool docollide =
false;
421 if (0 == (
m_pid % DBVT_BP_PROFILING_RATE))
424 unsigned int total = m_profiling.m_total;
425 if (total <= 0) total = 1;
426 printf(
"ddcollide: %u%% (%uus)\r\n", (50 + m_profiling.m_ddcollide * 100) / total, m_profiling.m_ddcollide / DBVT_BP_PROFILING_RATE);
427 printf(
"fdcollide: %u%% (%uus)\r\n", (50 + m_profiling.m_fdcollide * 100) / total, m_profiling.m_fdcollide / DBVT_BP_PROFILING_RATE);
428 printf(
"cleanup: %u%% (%uus)\r\n", (50 + m_profiling.m_cleanup * 100) / total, m_profiling.m_cleanup / DBVT_BP_PROFILING_RATE);
429 printf(
"total: %uus\r\n", total / DBVT_BP_PROFILING_RATE);
430 const unsigned long sum = m_profiling.m_ddcollide +
431 m_profiling.m_fdcollide +
432 m_profiling.m_cleanup;
433 printf(
"leaked: %u%% (%uus)\r\n", 100 - ((50 +
sum * 100) / total), (total -
sum) / DBVT_BP_PROFILING_RATE);
461 for (i = 0; i < overlappingPairArray.
size(); i++)
465 bool isDuplicate = (pair == previousPair);
469 bool needsRemoval =
false;
480 needsRemoval =
false;
507 overlappingPairArray.
resize(overlappingPairArray.
size() - invalidPair);
529 SPC(m_profiling.m_total);
543#if DBVT_BP_ACCURATESLEEPING
551#if DBVT_BP_ACCURATESLEEPING
553 collider.
proxy = current;
572 SPC(m_profiling.m_fdcollide);
577 SPC(m_profiling.m_ddcollide);
584 SPC(m_profiling.m_cleanup);
586 if (pairs.
size() > 0)
589 for (
int i = 0; i < ni; ++i)
605 if (pairs.
size() > 0)
657 else if (!
m_sets[1].empty())
702#if DBVT_BP_ENABLE_BENCHMARK
704struct btBroadphaseBenchmark
726 btSin(time) * amplitude / 2;
728 btSin(time) * amplitude;
730 pbi->
setAabb(proxy, center - extents, center + extents, 0);
733 static int UnsignedRand(
int range = RAND_MAX - 1) {
return (rand() % (range + 1)); }
734 static btScalar UnitRand() {
return (UnsignedRand(16384) / (
btScalar)16384); }
735 static void OutputTime(
const char* name,
btClock& c,
unsigned count = 0)
738 const unsigned long ms = (us + 500) / 1000;
741 printf(
"%s : %u us (%u ms), %.2f/s\r\n", name, us, ms, count / sec);
743 printf(
"%s : %u us (%u ms)\r\n", name, us, ms);
749 static const btBroadphaseBenchmark::Experiment experiments[] =
755 static const int nexperiments =
sizeof(experiments) /
sizeof(experiments[0]);
759 for (
int iexp = 0; iexp < nexperiments; ++iexp)
761 const btBroadphaseBenchmark::Experiment& experiment = experiments[iexp];
762 const int object_count = experiment.object_count;
763 const int update_count = (object_count * experiment.update_count) / 100;
764 const int spawn_count = (object_count * experiment.spawn_count) / 100;
765 const btScalar speed = experiment.speed;
766 const btScalar amplitude = experiment.amplitude;
767 printf(
"Experiment #%u '%s':\r\n", iexp, experiment.name);
768 printf(
"\tObjects: %u\r\n", object_count);
769 printf(
"\tUpdate: %u\r\n", update_count);
770 printf(
"\tSpawn: %u\r\n", spawn_count);
771 printf(
"\tSpeed: %f\r\n", speed);
772 printf(
"\tAmplitude: %f\r\n", amplitude);
777 for (
int i = 0; i < object_count; ++i)
779 btBroadphaseBenchmark::Object* po =
new btBroadphaseBenchmark::Object();
780 po->center[0] = btBroadphaseBenchmark::UnitRand() * 50;
781 po->center[1] = btBroadphaseBenchmark::UnitRand() * 50;
782 po->center[2] = btBroadphaseBenchmark::UnitRand() * 50;
783 po->extents[0] = btBroadphaseBenchmark::UnitRand() * 2 + 2;
784 po->extents[1] = btBroadphaseBenchmark::UnitRand() * 2 + 2;
785 po->extents[2] = btBroadphaseBenchmark::UnitRand() * 2 + 2;
786 po->time = btBroadphaseBenchmark::UnitRand() * 2000;
787 po->proxy = pbi->
createProxy(po->center - po->extents, po->center + po->extents, 0, po, 1, 1, 0, 0);
790 btBroadphaseBenchmark::OutputTime(
"\tInitialization", wallclock);
793 for (
int i = 0; i < objects.
size(); ++i)
795 objects[i]->update(speed, amplitude, pbi);
797 btBroadphaseBenchmark::OutputTime(
"\tFirst update", wallclock);
800 for (
int i = 0; i < experiment.iterations; ++i)
802 for (
int j = 0; j < update_count; ++j)
804 objects[j]->update(speed, amplitude, pbi);
808 btBroadphaseBenchmark::OutputTime(
"\tUpdate", wallclock, experiment.iterations);
811 for (
int i = 0; i < objects.
size(); ++i)
817 btBroadphaseBenchmark::OutputTime(
"\tRelease", wallclock);
#define btAlignedFree(ptr)
#define btAlignedAlloc(size, alignment)
static void clear(T &value)
static void listappend(T *item, T *&list)
static int listcount(T *root)
static void listremove(T *item, T *&list)
btScalar gDbvtMargin
btDbvtBroadphase implementation by Nathanael Presson
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.
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...
btAlignedObjectArray< btAlignedObjectArray< const btDbvtNode * > > m_rayTestStacks
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)