2
Bullet Continuous Collision Detection and Physics Library
3
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
5
This software is provided 'as-is', without any express or implied warranty.
6
In no event will the authors be held liable for any damages arising from the use of this software.
7
Permission is granted to anyone to use this software for any purpose,
8
including commercial applications, and to alter it and redistribute it freely,
9
subject to the following restrictions:
11
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.
12
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13
3. This notice may not be removed or altered from any source distribution.
15
///btDbvt implementation by Nathanael Presson
20
typedef btAlignedObjectArray<btDbvtNode*> tNodeArray;
21
typedef btAlignedObjectArray<const btDbvtNode*> tConstNodeArray;
24
struct btDbvtNodeEnumerator : btDbvt::ICollide
26
tConstNodeArray nodes;
27
void Process(const btDbvtNode* n) { nodes.push_back(n); }
31
static DBVT_INLINE int indexof(const btDbvtNode* node)
33
return(node->parent->childs[1]==node);
37
static DBVT_INLINE btDbvtVolume merge( const btDbvtVolume& a,
38
const btDbvtVolume& b)
40
#if (DBVT_MERGE_IMPL==DBVT_IMPL_SSE)
41
ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtAabbMm)]);
42
btDbvtVolume& res=*(btDbvtVolume*)locals;
50
// volume+edge lengths
51
static DBVT_INLINE btScalar size(const btDbvtVolume& a)
53
const btVector3 edges=a.Lengths();
54
return( edges.x()*edges.y()*edges.z()+
55
edges.x()+edges.y()+edges.z());
59
static void getmaxdepth(const btDbvtNode* node,int depth,int& maxdepth)
61
if(node->isinternal())
63
getmaxdepth(node->childs[0],depth+1,maxdepth);
64
getmaxdepth(node->childs[1],depth+1,maxdepth);
65
} else maxdepth=btMax(maxdepth,depth);
69
static DBVT_INLINE void deletenode( btDbvt* pdbvt,
72
btAlignedFree(pdbvt->m_free);
77
static void recursedeletenode( btDbvt* pdbvt,
82
recursedeletenode(pdbvt,node->childs[0]);
83
recursedeletenode(pdbvt,node->childs[1]);
85
if(node==pdbvt->m_root) pdbvt->m_root=0;
86
deletenode(pdbvt,node);
90
static DBVT_INLINE btDbvtNode* createnode( btDbvt* pdbvt,
96
{ node=pdbvt->m_free;pdbvt->m_free=0; }
98
{ node=new(btAlignedAlloc(sizeof(btDbvtNode),16)) btDbvtNode(); }
99
node->parent = parent;
106
static DBVT_INLINE btDbvtNode* createnode( btDbvt* pdbvt,
108
const btDbvtVolume& volume,
111
btDbvtNode* node=createnode(pdbvt,parent,data);
117
static DBVT_INLINE btDbvtNode* createnode( btDbvt* pdbvt,
119
const btDbvtVolume& volume0,
120
const btDbvtVolume& volume1,
123
btDbvtNode* node=createnode(pdbvt,parent,data);
124
Merge(volume0,volume1,node->volume);
129
static void insertleaf( btDbvt* pdbvt,
135
pdbvt->m_root = leaf;
143
root=root->childs[Select( leaf->volume,
144
root->childs[0]->volume,
145
root->childs[1]->volume)];
146
} while(!root->isleaf());
148
btDbvtNode* prev=root->parent;
149
btDbvtNode* node=createnode(pdbvt,prev,leaf->volume,root->volume,0);
152
prev->childs[indexof(root)] = node;
153
node->childs[0] = root;root->parent=node;
154
node->childs[1] = leaf;leaf->parent=node;
156
if(!prev->volume.Contain(node->volume))
157
Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume);
161
} while(0!=(prev=node->parent));
165
node->childs[0] = root;root->parent=node;
166
node->childs[1] = leaf;leaf->parent=node;
167
pdbvt->m_root = node;
173
static btDbvtNode* removeleaf( btDbvt* pdbvt,
176
if(leaf==pdbvt->m_root)
183
btDbvtNode* parent=leaf->parent;
184
btDbvtNode* prev=parent->parent;
185
btDbvtNode* sibling=parent->childs[1-indexof(leaf)];
188
prev->childs[indexof(parent)]=sibling;
189
sibling->parent=prev;
190
deletenode(pdbvt,parent);
193
const btDbvtVolume pb=prev->volume;
194
Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume);
195
if(NotEqual(pb,prev->volume))
200
return(prev?prev:pdbvt->m_root);
204
pdbvt->m_root=sibling;
206
deletenode(pdbvt,parent);
207
return(pdbvt->m_root);
213
static void fetchleaves(btDbvt* pdbvt,
218
if(root->isinternal()&&depth)
220
fetchleaves(pdbvt,root->childs[0],leaves,depth-1);
221
fetchleaves(pdbvt,root->childs[1],leaves,depth-1);
222
deletenode(pdbvt,root);
226
leaves.push_back(root);
231
static void split( const tNodeArray& leaves,
234
const btVector3& org,
235
const btVector3& axis)
239
for(int i=0,ni=leaves.size();i<ni;++i)
241
if(btDot(axis,leaves[i]->volume.Center()-org)<0)
242
left.push_back(leaves[i]);
244
right.push_back(leaves[i]);
249
static btDbvtVolume bounds( const tNodeArray& leaves)
251
#if DBVT_MERGE_IMPL==DBVT_IMPL_SSE
252
ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtVolume)]);
253
btDbvtVolume& volume=*(btDbvtVolume*)locals;
254
volume=leaves[0]->volume;
256
btDbvtVolume volume=leaves[0]->volume;
258
for(int i=1,ni=leaves.size();i<ni;++i)
260
Merge(volume,leaves[i]->volume,volume);
266
static void bottomup( btDbvt* pdbvt,
269
while(leaves.size()>1)
271
btScalar minsize=SIMD_INFINITY;
272
int minidx[2]={-1,-1};
273
for(int i=0;i<leaves.size();++i)
275
for(int j=i+1;j<leaves.size();++j)
277
const btScalar sz=size(merge(leaves[i]->volume,leaves[j]->volume));
286
btDbvtNode* n[] = {leaves[minidx[0]],leaves[minidx[1]]};
287
btDbvtNode* p = createnode(pdbvt,0,n[0]->volume,n[1]->volume,0);
292
leaves[minidx[0]] = p;
293
leaves.swap(minidx[1],leaves.size()-1);
299
static btDbvtNode* topdown(btDbvt* pdbvt,
303
static const btVector3 axis[]={btVector3(1,0,0),
308
if(leaves.size()>bu_treshold)
310
const btDbvtVolume vol=bounds(leaves);
311
const btVector3 org=vol.Center();
314
int bestmidp=leaves.size();
315
int splitcount[3][2]={{0,0},{0,0},{0,0}};
317
for( i=0;i<leaves.size();++i)
319
const btVector3 x=leaves[i]->volume.Center()-org;
322
++splitcount[j][btDot(x,axis[j])>0?1:0];
327
if((splitcount[i][0]>0)&&(splitcount[i][1]>0))
329
const int midp=(int)btFabs(btScalar(splitcount[i][0]-splitcount[i][1]));
339
sets[0].reserve(splitcount[bestaxis][0]);
340
sets[1].reserve(splitcount[bestaxis][1]);
341
split(leaves,sets[0],sets[1],org,axis[bestaxis]);
345
sets[0].reserve(leaves.size()/2+1);
346
sets[1].reserve(leaves.size()/2);
347
for(int i=0,ni=leaves.size();i<ni;++i)
349
sets[i&1].push_back(leaves[i]);
352
btDbvtNode* node=createnode(pdbvt,0,vol,0);
353
node->childs[0]=topdown(pdbvt,sets[0],bu_treshold);
354
node->childs[1]=topdown(pdbvt,sets[1],bu_treshold);
355
node->childs[0]->parent=node;
356
node->childs[1]->parent=node;
361
bottomup(pdbvt,leaves);
369
static DBVT_INLINE btDbvtNode* sort(btDbvtNode* n,btDbvtNode*& r)
371
btDbvtNode* p=n->parent;
372
btAssert(n->isinternal());
375
const int i=indexof(n);
377
btDbvtNode* s=p->childs[j];
378
btDbvtNode* q=p->parent;
379
btAssert(n==p->childs[i]);
380
if(q) q->childs[indexof(p)]=n; else r=n;
384
p->childs[0]=n->childs[0];
385
p->childs[1]=n->childs[1];
386
n->childs[0]->parent=p;
387
n->childs[1]->parent=p;
390
btSwap(p->volume,n->volume);
397
static DBVT_INLINE btDbvtNode* walkup(btDbvtNode* n,int count)
399
while(n&&(count--)) n=n->parent;
428
recursedeletenode(this,m_root);
429
btAlignedFree(m_free);
438
void btDbvt::optimizeBottomUp()
443
leaves.reserve(m_leaves);
444
fetchleaves(this,m_root,leaves);
445
bottomup(this,leaves);
451
void btDbvt::optimizeTopDown(int bu_treshold)
456
leaves.reserve(m_leaves);
457
fetchleaves(this,m_root,leaves);
458
m_root=topdown(this,leaves,bu_treshold);
463
void btDbvt::optimizeIncremental(int passes)
465
if(passes<0) passes=m_leaves;
466
if(m_root&&(passes>0))
469
btDbvtNode* node=m_root;
471
while(node->isinternal())
473
node=sort(node,m_root)->childs[(m_opath>>bit)&1];
474
bit=(bit+1)&(sizeof(unsigned)*8-1);
483
btDbvtNode* btDbvt::insert(const btDbvtVolume& volume,void* data)
485
btDbvtNode* leaf=createnode(this,0,volume,data);
486
insertleaf(this,m_root,leaf);
492
void btDbvt::update(btDbvtNode* leaf,int lookahead)
494
btDbvtNode* root=removeleaf(this,leaf);
499
for(int i=0;(i<lookahead)&&root->parent;++i)
505
insertleaf(this,root,leaf);
509
void btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume)
511
btDbvtNode* root=removeleaf(this,leaf);
516
for(int i=0;(i<m_lkhd)&&root->parent;++i)
523
insertleaf(this,root,leaf);
527
bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity,btScalar margin)
529
if(leaf->volume.Contain(volume)) return(false);
530
volume.Expand(btVector3(margin,margin,margin));
531
volume.SignedExpand(velocity);
537
bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity)
539
if(leaf->volume.Contain(volume)) return(false);
540
volume.SignedExpand(velocity);
546
bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,btScalar margin)
548
if(leaf->volume.Contain(volume)) return(false);
549
volume.Expand(btVector3(margin,margin,margin));
555
void btDbvt::remove(btDbvtNode* leaf)
557
removeleaf(this,leaf);
558
deletenode(this,leaf);
563
void btDbvt::write(IWriter* iwriter) const
565
btDbvtNodeEnumerator nodes;
566
nodes.nodes.reserve(m_leaves*2);
567
enumNodes(m_root,nodes);
568
iwriter->Prepare(m_root,nodes.nodes.size());
569
for(int i=0;i<nodes.nodes.size();++i)
571
const btDbvtNode* n=nodes.nodes[i];
573
if(n->parent) p=nodes.nodes.findLinearSearch(n->parent);
576
const int c0=nodes.nodes.findLinearSearch(n->childs[0]);
577
const int c1=nodes.nodes.findLinearSearch(n->childs[1]);
578
iwriter->WriteNode(n,i,p,c0,c1);
582
iwriter->WriteLeaf(n,i,p);
588
void btDbvt::clone(btDbvt& dest,IClone* iclone) const
593
btAlignedObjectArray<sStkCLN> stack;
594
stack.reserve(m_leaves);
595
stack.push_back(sStkCLN(m_root,0));
597
const int i=stack.size()-1;
598
const sStkCLN e=stack[i];
599
btDbvtNode* n=createnode(&dest,e.parent,e.node->volume,e.node->data);
602
e.parent->childs[i&1]=n;
605
if(e.node->isinternal())
607
stack.push_back(sStkCLN(e.node->childs[0],n));
608
stack.push_back(sStkCLN(e.node->childs[1],n));
612
iclone->CloneLeaf(n);
614
} while(stack.size()>0);
619
int btDbvt::maxdepth(const btDbvtNode* node)
622
if(node) getmaxdepth(node,1,depth);
627
int btDbvt::countLeaves(const btDbvtNode* node)
629
if(node->isinternal())
630
return(countLeaves(node->childs[0])+countLeaves(node->childs[1]));
636
void btDbvt::extractLeaves(const btDbvtNode* node,btAlignedObjectArray<const btDbvtNode*>& leaves)
638
if(node->isinternal())
640
extractLeaves(node->childs[0],leaves);
641
extractLeaves(node->childs[1],leaves);
645
leaves.push_back(node);
650
#if DBVT_ENABLE_BENCHMARK
654
#include "LinearMath/btQuickProf.h"
659
/Ox /Ob2 /Oi /Ot /I "." /I "..\.." /I "..\..\src" /D "NDEBUG" /D "_LIB" /D "_WINDOWS" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "WIN32"
660
/GF /FD /MT /GS- /Gy /arch:SSE2 /Zc:wchar_t- /Fp"..\..\out\release8\build\libbulletcollision\libbulletcollision.pch"
661
/Fo"..\..\out\release8\build\libbulletcollision\\"
662
/Fd"..\..\out\release8\build\libbulletcollision\bulletcollision.pdb"
663
/W3 /nologo /c /Wp64 /Zi /errorReport:prompt
666
World scale: 100.000000
667
Extents base: 1.000000
668
Extents range: 4.000000
670
sizeof(btDbvtVolume): 32 bytes
671
sizeof(btDbvtNode): 44 bytes
672
[1] btDbvtVolume intersections: 3499 ms (-1%)
673
[2] btDbvtVolume merges: 1934 ms (0%)
674
[3] btDbvt::collideTT: 5485 ms (-21%)
675
[4] btDbvt::collideTT self: 2814 ms (-20%)
676
[5] btDbvt::collideTT xform: 7379 ms (-1%)
677
[6] btDbvt::collideTT xform,self: 7270 ms (-2%)
678
[7] btDbvt::rayTest: 6314 ms (0%),(332143 r/s)
679
[8] insert/remove: 2093 ms (0%),(1001983 ir/s)
680
[9] updates (teleport): 1879 ms (-3%),(1116100 u/s)
681
[10] updates (jitter): 1244 ms (-4%),(1685813 u/s)
682
[11] optimize (incremental): 2514 ms (0%),(1668000 o/s)
683
[12] btDbvtVolume notequal: 3659 ms (0%)
684
[13] culling(OCL+fullsort): 2218 ms (0%),(461 t/s)
685
[14] culling(OCL+qsort): 3688 ms (5%),(2221 t/s)
686
[15] culling(KDOP+qsort): 1139 ms (-1%),(7192 t/s)
687
[16] insert/remove batch(256): 5092 ms (0%),(823704 bir/s)
688
[17] btDbvtVolume select: 3419 ms (0%)
691
struct btDbvtBenchmark
693
struct NilPolicy : btDbvt::ICollide
695
NilPolicy() : m_pcount(0),m_depth(-SIMD_INFINITY),m_checksort(true) {}
696
void Process(const btDbvtNode*,const btDbvtNode*) { ++m_pcount; }
697
void Process(const btDbvtNode*) { ++m_pcount; }
698
void Process(const btDbvtNode*,btScalar depth)
702
{ if(depth>=m_depth) m_depth=depth; else printf("wrong depth: %f (should be >= %f)\r\n",depth,m_depth); }
708
struct P14 : btDbvt::ICollide
712
const btDbvtNode* leaf;
715
void Process(const btDbvtNode* leaf,btScalar depth)
721
static int sortfnc(const Node& a,const Node& b)
723
if(a.depth<b.depth) return(+1);
724
if(a.depth>b.depth) return(-1);
727
btAlignedObjectArray<Node> m_nodes;
729
struct P15 : btDbvt::ICollide
733
const btDbvtNode* leaf;
736
void Process(const btDbvtNode* leaf)
740
n.depth = dot(leaf->volume.Center(),m_axis);
742
static int sortfnc(const Node& a,const Node& b)
744
if(a.depth<b.depth) return(+1);
745
if(a.depth>b.depth) return(-1);
748
btAlignedObjectArray<Node> m_nodes;
751
static btScalar RandUnit()
753
return(rand()/(btScalar)RAND_MAX);
755
static btVector3 RandVector3()
757
return(btVector3(RandUnit(),RandUnit(),RandUnit()));
759
static btVector3 RandVector3(btScalar cs)
761
return(RandVector3()*cs-btVector3(cs,cs,cs)/2);
763
static btDbvtVolume RandVolume(btScalar cs,btScalar eb,btScalar es)
765
return(btDbvtVolume::FromCE(RandVector3(cs),btVector3(eb,eb,eb)+RandVector3()*es));
767
static btTransform RandTransform(btScalar cs)
770
t.setOrigin(RandVector3(cs));
771
t.setRotation(btQuaternion(RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2).normalized());
774
static void RandTree(btScalar cs,btScalar eb,btScalar es,int leaves,btDbvt& dbvt)
777
for(int i=0;i<leaves;++i)
779
dbvt.insert(RandVolume(cs,eb,es),0);
784
void btDbvt::benchmark()
786
static const btScalar cfgVolumeCenterScale = 100;
787
static const btScalar cfgVolumeExentsBase = 1;
788
static const btScalar cfgVolumeExentsScale = 4;
789
static const int cfgLeaves = 8192;
790
static const bool cfgEnable = true;
792
//[1] btDbvtVolume intersections
793
bool cfgBenchmark1_Enable = cfgEnable;
794
static const int cfgBenchmark1_Iterations = 8;
795
static const int cfgBenchmark1_Reference = 3499;
796
//[2] btDbvtVolume merges
797
bool cfgBenchmark2_Enable = cfgEnable;
798
static const int cfgBenchmark2_Iterations = 4;
799
static const int cfgBenchmark2_Reference = 1945;
800
//[3] btDbvt::collideTT
801
bool cfgBenchmark3_Enable = cfgEnable;
802
static const int cfgBenchmark3_Iterations = 512;
803
static const int cfgBenchmark3_Reference = 5485;
804
//[4] btDbvt::collideTT self
805
bool cfgBenchmark4_Enable = cfgEnable;
806
static const int cfgBenchmark4_Iterations = 512;
807
static const int cfgBenchmark4_Reference = 2814;
808
//[5] btDbvt::collideTT xform
809
bool cfgBenchmark5_Enable = cfgEnable;
810
static const int cfgBenchmark5_Iterations = 512;
811
static const btScalar cfgBenchmark5_OffsetScale = 2;
812
static const int cfgBenchmark5_Reference = 7379;
813
//[6] btDbvt::collideTT xform,self
814
bool cfgBenchmark6_Enable = cfgEnable;
815
static const int cfgBenchmark6_Iterations = 512;
816
static const btScalar cfgBenchmark6_OffsetScale = 2;
817
static const int cfgBenchmark6_Reference = 7270;
818
//[7] btDbvt::rayTest
819
bool cfgBenchmark7_Enable = cfgEnable;
820
static const int cfgBenchmark7_Passes = 32;
821
static const int cfgBenchmark7_Iterations = 65536;
822
static const int cfgBenchmark7_Reference = 6307;
824
bool cfgBenchmark8_Enable = cfgEnable;
825
static const int cfgBenchmark8_Passes = 32;
826
static const int cfgBenchmark8_Iterations = 65536;
827
static const int cfgBenchmark8_Reference = 2105;
828
//[9] updates (teleport)
829
bool cfgBenchmark9_Enable = cfgEnable;
830
static const int cfgBenchmark9_Passes = 32;
831
static const int cfgBenchmark9_Iterations = 65536;
832
static const int cfgBenchmark9_Reference = 1879;
833
//[10] updates (jitter)
834
bool cfgBenchmark10_Enable = cfgEnable;
835
static const btScalar cfgBenchmark10_Scale = cfgVolumeCenterScale/10000;
836
static const int cfgBenchmark10_Passes = 32;
837
static const int cfgBenchmark10_Iterations = 65536;
838
static const int cfgBenchmark10_Reference = 1244;
839
//[11] optimize (incremental)
840
bool cfgBenchmark11_Enable = cfgEnable;
841
static const int cfgBenchmark11_Passes = 64;
842
static const int cfgBenchmark11_Iterations = 65536;
843
static const int cfgBenchmark11_Reference = 2510;
844
//[12] btDbvtVolume notequal
845
bool cfgBenchmark12_Enable = cfgEnable;
846
static const int cfgBenchmark12_Iterations = 32;
847
static const int cfgBenchmark12_Reference = 3677;
848
//[13] culling(OCL+fullsort)
849
bool cfgBenchmark13_Enable = cfgEnable;
850
static const int cfgBenchmark13_Iterations = 1024;
851
static const int cfgBenchmark13_Reference = 2231;
852
//[14] culling(OCL+qsort)
853
bool cfgBenchmark14_Enable = cfgEnable;
854
static const int cfgBenchmark14_Iterations = 8192;
855
static const int cfgBenchmark14_Reference = 3500;
856
//[15] culling(KDOP+qsort)
857
bool cfgBenchmark15_Enable = cfgEnable;
858
static const int cfgBenchmark15_Iterations = 8192;
859
static const int cfgBenchmark15_Reference = 1151;
860
//[16] insert/remove batch
861
bool cfgBenchmark16_Enable = cfgEnable;
862
static const int cfgBenchmark16_BatchCount = 256;
863
static const int cfgBenchmark16_Passes = 16384;
864
static const int cfgBenchmark16_Reference = 5138;
866
bool cfgBenchmark17_Enable = cfgEnable;
867
static const int cfgBenchmark17_Iterations = 4;
868
static const int cfgBenchmark17_Reference = 3390;
871
printf("Benchmarking dbvt...\r\n");
872
printf("\tWorld scale: %f\r\n",cfgVolumeCenterScale);
873
printf("\tExtents base: %f\r\n",cfgVolumeExentsBase);
874
printf("\tExtents range: %f\r\n",cfgVolumeExentsScale);
875
printf("\tLeaves: %u\r\n",cfgLeaves);
876
printf("\tsizeof(btDbvtVolume): %u bytes\r\n",sizeof(btDbvtVolume));
877
printf("\tsizeof(btDbvtNode): %u bytes\r\n",sizeof(btDbvtNode));
878
if(cfgBenchmark1_Enable)
881
btAlignedObjectArray<btDbvtVolume> volumes;
882
btAlignedObjectArray<bool> results;
883
volumes.resize(cfgLeaves);
884
results.resize(cfgLeaves);
885
for(int i=0;i<cfgLeaves;++i)
887
volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
889
printf("[1] btDbvtVolume intersections: ");
891
for(int i=0;i<cfgBenchmark1_Iterations;++i)
893
for(int j=0;j<cfgLeaves;++j)
895
for(int k=0;k<cfgLeaves;++k)
897
results[k]=Intersect(volumes[j],volumes[k]);
901
const int time=(int)wallclock.getTimeMilliseconds();
902
printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark1_Reference)*100/time);
904
if(cfgBenchmark2_Enable)
907
btAlignedObjectArray<btDbvtVolume> volumes;
908
btAlignedObjectArray<btDbvtVolume> results;
909
volumes.resize(cfgLeaves);
910
results.resize(cfgLeaves);
911
for(int i=0;i<cfgLeaves;++i)
913
volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
915
printf("[2] btDbvtVolume merges: ");
917
for(int i=0;i<cfgBenchmark2_Iterations;++i)
919
for(int j=0;j<cfgLeaves;++j)
921
for(int k=0;k<cfgLeaves;++k)
923
Merge(volumes[j],volumes[k],results[k]);
927
const int time=(int)wallclock.getTimeMilliseconds();
928
printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark2_Reference)*100/time);
930
if(cfgBenchmark3_Enable)
934
btDbvtBenchmark::NilPolicy policy;
935
btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]);
936
btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]);
937
dbvt[0].optimizeTopDown();
938
dbvt[1].optimizeTopDown();
939
printf("[3] btDbvt::collideTT: ");
941
for(int i=0;i<cfgBenchmark3_Iterations;++i)
943
btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,policy);
945
const int time=(int)wallclock.getTimeMilliseconds();
946
printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark3_Reference)*100/time);
948
if(cfgBenchmark4_Enable)
952
btDbvtBenchmark::NilPolicy policy;
953
btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
954
dbvt.optimizeTopDown();
955
printf("[4] btDbvt::collideTT self: ");
957
for(int i=0;i<cfgBenchmark4_Iterations;++i)
959
btDbvt::collideTT(dbvt.m_root,dbvt.m_root,policy);
961
const int time=(int)wallclock.getTimeMilliseconds();
962
printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark4_Reference)*100/time);
964
if(cfgBenchmark5_Enable)
968
btAlignedObjectArray<btTransform> transforms;
969
btDbvtBenchmark::NilPolicy policy;
970
transforms.resize(cfgBenchmark5_Iterations);
971
for(int i=0;i<transforms.size();++i)
973
transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark5_OffsetScale);
975
btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]);
976
btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]);
977
dbvt[0].optimizeTopDown();
978
dbvt[1].optimizeTopDown();
979
printf("[5] btDbvt::collideTT xform: ");
981
for(int i=0;i<cfgBenchmark5_Iterations;++i)
983
btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,transforms[i],policy);
985
const int time=(int)wallclock.getTimeMilliseconds();
986
printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark5_Reference)*100/time);
988
if(cfgBenchmark6_Enable)
992
btAlignedObjectArray<btTransform> transforms;
993
btDbvtBenchmark::NilPolicy policy;
994
transforms.resize(cfgBenchmark6_Iterations);
995
for(int i=0;i<transforms.size();++i)
997
transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark6_OffsetScale);
999
btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
1000
dbvt.optimizeTopDown();
1001
printf("[6] btDbvt::collideTT xform,self: ");
1003
for(int i=0;i<cfgBenchmark6_Iterations;++i)
1005
btDbvt::collideTT(dbvt.m_root,dbvt.m_root,transforms[i],policy);
1007
const int time=(int)wallclock.getTimeMilliseconds();
1008
printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark6_Reference)*100/time);
1010
if(cfgBenchmark7_Enable)
1014
btAlignedObjectArray<btVector3> rayorg;
1015
btAlignedObjectArray<btVector3> raydir;
1016
btDbvtBenchmark::NilPolicy policy;
1017
rayorg.resize(cfgBenchmark7_Iterations);
1018
raydir.resize(cfgBenchmark7_Iterations);
1019
for(int i=0;i<rayorg.size();++i)
1021
rayorg[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2);
1022
raydir[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2);
1024
btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
1025
dbvt.optimizeTopDown();
1026
printf("[7] btDbvt::rayTest: ");
1028
for(int i=0;i<cfgBenchmark7_Passes;++i)
1030
for(int j=0;j<cfgBenchmark7_Iterations;++j)
1032
btDbvt::rayTest(dbvt.m_root,rayorg[j],rayorg[j]+raydir[j],policy);
1035
const int time=(int)wallclock.getTimeMilliseconds();
1036
unsigned rays=cfgBenchmark7_Passes*cfgBenchmark7_Iterations;
1037
printf("%u ms (%i%%),(%u r/s)\r\n",time,(time-cfgBenchmark7_Reference)*100/time,(rays*1000)/time);
1039
if(cfgBenchmark8_Enable)
1043
btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
1044
dbvt.optimizeTopDown();
1045
printf("[8] insert/remove: ");
1047
for(int i=0;i<cfgBenchmark8_Passes;++i)
1049
for(int j=0;j<cfgBenchmark8_Iterations;++j)
1051
dbvt.remove(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0));
1054
const int time=(int)wallclock.getTimeMilliseconds();
1055
const int ir=cfgBenchmark8_Passes*cfgBenchmark8_Iterations;
1056
printf("%u ms (%i%%),(%u ir/s)\r\n",time,(time-cfgBenchmark8_Reference)*100/time,ir*1000/time);
1058
if(cfgBenchmark9_Enable)
1062
btAlignedObjectArray<const btDbvtNode*> leaves;
1063
btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
1064
dbvt.optimizeTopDown();
1065
dbvt.extractLeaves(dbvt.m_root,leaves);
1066
printf("[9] updates (teleport): ");
1068
for(int i=0;i<cfgBenchmark9_Passes;++i)
1070
for(int j=0;j<cfgBenchmark9_Iterations;++j)
1072
dbvt.update(const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]),
1073
btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale));
1076
const int time=(int)wallclock.getTimeMilliseconds();
1077
const int up=cfgBenchmark9_Passes*cfgBenchmark9_Iterations;
1078
printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark9_Reference)*100/time,up*1000/time);
1080
if(cfgBenchmark10_Enable)
1084
btAlignedObjectArray<const btDbvtNode*> leaves;
1085
btAlignedObjectArray<btVector3> vectors;
1086
vectors.resize(cfgBenchmark10_Iterations);
1087
for(int i=0;i<vectors.size();++i)
1089
vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1))*cfgBenchmark10_Scale;
1091
btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
1092
dbvt.optimizeTopDown();
1093
dbvt.extractLeaves(dbvt.m_root,leaves);
1094
printf("[10] updates (jitter): ");
1097
for(int i=0;i<cfgBenchmark10_Passes;++i)
1099
for(int j=0;j<cfgBenchmark10_Iterations;++j)
1101
const btVector3& d=vectors[j];
1102
btDbvtNode* l=const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]);
1103
btDbvtVolume v=btDbvtVolume::FromMM(l->volume.Mins()+d,l->volume.Maxs()+d);
1107
const int time=(int)wallclock.getTimeMilliseconds();
1108
const int up=cfgBenchmark10_Passes*cfgBenchmark10_Iterations;
1109
printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark10_Reference)*100/time,up*1000/time);
1111
if(cfgBenchmark11_Enable)
1115
btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
1116
dbvt.optimizeTopDown();
1117
printf("[11] optimize (incremental): ");
1119
for(int i=0;i<cfgBenchmark11_Passes;++i)
1121
dbvt.optimizeIncremental(cfgBenchmark11_Iterations);
1123
const int time=(int)wallclock.getTimeMilliseconds();
1124
const int op=cfgBenchmark11_Passes*cfgBenchmark11_Iterations;
1125
printf("%u ms (%i%%),(%u o/s)\r\n",time,(time-cfgBenchmark11_Reference)*100/time,op/time*1000);
1127
if(cfgBenchmark12_Enable)
1130
btAlignedObjectArray<btDbvtVolume> volumes;
1131
btAlignedObjectArray<bool> results;
1132
volumes.resize(cfgLeaves);
1133
results.resize(cfgLeaves);
1134
for(int i=0;i<cfgLeaves;++i)
1136
volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
1138
printf("[12] btDbvtVolume notequal: ");
1140
for(int i=0;i<cfgBenchmark12_Iterations;++i)
1142
for(int j=0;j<cfgLeaves;++j)
1144
for(int k=0;k<cfgLeaves;++k)
1146
results[k]=NotEqual(volumes[j],volumes[k]);
1150
const int time=(int)wallclock.getTimeMilliseconds();
1151
printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark12_Reference)*100/time);
1153
if(cfgBenchmark13_Enable)
1157
btAlignedObjectArray<btVector3> vectors;
1158
btDbvtBenchmark::NilPolicy policy;
1159
vectors.resize(cfgBenchmark13_Iterations);
1160
for(int i=0;i<vectors.size();++i)
1162
vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
1164
btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
1165
dbvt.optimizeTopDown();
1166
printf("[13] culling(OCL+fullsort): ");
1168
for(int i=0;i<cfgBenchmark13_Iterations;++i)
1170
static const btScalar offset=0;
1171
policy.m_depth=-SIMD_INFINITY;
1172
dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy);
1174
const int time=(int)wallclock.getTimeMilliseconds();
1175
const int t=cfgBenchmark13_Iterations;
1176
printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark13_Reference)*100/time,(t*1000)/time);
1178
if(cfgBenchmark14_Enable)
1182
btAlignedObjectArray<btVector3> vectors;
1183
btDbvtBenchmark::P14 policy;
1184
vectors.resize(cfgBenchmark14_Iterations);
1185
for(int i=0;i<vectors.size();++i)
1187
vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
1189
btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
1190
dbvt.optimizeTopDown();
1191
policy.m_nodes.reserve(cfgLeaves);
1192
printf("[14] culling(OCL+qsort): ");
1194
for(int i=0;i<cfgBenchmark14_Iterations;++i)
1196
static const btScalar offset=0;
1197
policy.m_nodes.resize(0);
1198
dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy,false);
1199
policy.m_nodes.quickSort(btDbvtBenchmark::P14::sortfnc);
1201
const int time=(int)wallclock.getTimeMilliseconds();
1202
const int t=cfgBenchmark14_Iterations;
1203
printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark14_Reference)*100/time,(t*1000)/time);
1205
if(cfgBenchmark15_Enable)
1209
btAlignedObjectArray<btVector3> vectors;
1210
btDbvtBenchmark::P15 policy;
1211
vectors.resize(cfgBenchmark15_Iterations);
1212
for(int i=0;i<vectors.size();++i)
1214
vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
1216
btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
1217
dbvt.optimizeTopDown();
1218
policy.m_nodes.reserve(cfgLeaves);
1219
printf("[15] culling(KDOP+qsort): ");
1221
for(int i=0;i<cfgBenchmark15_Iterations;++i)
1223
static const btScalar offset=0;
1224
policy.m_nodes.resize(0);
1225
policy.m_axis=vectors[i];
1226
dbvt.collideKDOP(dbvt.m_root,&vectors[i],&offset,1,policy);
1227
policy.m_nodes.quickSort(btDbvtBenchmark::P15::sortfnc);
1229
const int time=(int)wallclock.getTimeMilliseconds();
1230
const int t=cfgBenchmark15_Iterations;
1231
printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark15_Reference)*100/time,(t*1000)/time);
1233
if(cfgBenchmark16_Enable)
1237
btAlignedObjectArray<btDbvtNode*> batch;
1238
btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
1239
dbvt.optimizeTopDown();
1240
batch.reserve(cfgBenchmark16_BatchCount);
1241
printf("[16] insert/remove batch(%u): ",cfgBenchmark16_BatchCount);
1243
for(int i=0;i<cfgBenchmark16_Passes;++i)
1245
for(int j=0;j<cfgBenchmark16_BatchCount;++j)
1247
batch.push_back(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0));
1249
for(int j=0;j<cfgBenchmark16_BatchCount;++j)
1251
dbvt.remove(batch[j]);
1255
const int time=(int)wallclock.getTimeMilliseconds();
1256
const int ir=cfgBenchmark16_Passes*cfgBenchmark16_BatchCount;
1257
printf("%u ms (%i%%),(%u bir/s)\r\n",time,(time-cfgBenchmark16_Reference)*100/time,int(ir*1000.0/time));
1259
if(cfgBenchmark17_Enable)
1262
btAlignedObjectArray<btDbvtVolume> volumes;
1263
btAlignedObjectArray<int> results;
1264
btAlignedObjectArray<int> indices;
1265
volumes.resize(cfgLeaves);
1266
results.resize(cfgLeaves);
1267
indices.resize(cfgLeaves);
1268
for(int i=0;i<cfgLeaves;++i)
1271
volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
1273
for(int i=0;i<cfgLeaves;++i)
1275
btSwap(indices[i],indices[rand()%cfgLeaves]);
1277
printf("[17] btDbvtVolume select: ");
1279
for(int i=0;i<cfgBenchmark17_Iterations;++i)
1281
for(int j=0;j<cfgLeaves;++j)
1283
for(int k=0;k<cfgLeaves;++k)
1285
const int idx=indices[k];
1286
results[idx]=Select(volumes[idx],volumes[j],volumes[k]);
1290
const int time=(int)wallclock.getTimeMilliseconds();
1291
printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark17_Reference)*100/time);