12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358 |
- /*
- Bullet Continuous Collision Detection and Physics Library
- Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
- 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.
- */
- ///btDbvt implementation by Nathanael Presson
- #include "btDbvt.h"
- //
- typedef btAlignedObjectArray<btDbvtNode*> tNodeArray;
- typedef btAlignedObjectArray<const btDbvtNode*> tConstNodeArray;
- //
- struct btDbvtNodeEnumerator : btDbvt::ICollide
- {
- tConstNodeArray nodes;
- void Process(const btDbvtNode* n) { nodes.push_back(n); }
- };
- //
- static DBVT_INLINE int indexof(const btDbvtNode* node)
- {
- return (node->parent->childs[1] == node);
- }
- //
- static DBVT_INLINE btDbvtVolume merge(const btDbvtVolume& a,
- const btDbvtVolume& b)
- {
- #ifdef BT_USE_SSE
- ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtAabbMm)]);
- btDbvtVolume* ptr = (btDbvtVolume*)locals;
- btDbvtVolume& res = *ptr;
- #else
- btDbvtVolume res;
- #endif
- Merge(a, b, res);
- return (res);
- }
- // volume+edge lengths
- static DBVT_INLINE btScalar size(const btDbvtVolume& a)
- {
- const btVector3 edges = a.Lengths();
- return (edges.x() * edges.y() * edges.z() +
- edges.x() + edges.y() + edges.z());
- }
- //
- static void getmaxdepth(const btDbvtNode* node, int depth, int& maxdepth)
- {
- if (node->isinternal())
- {
- getmaxdepth(node->childs[0], depth + 1, maxdepth);
- getmaxdepth(node->childs[1], depth + 1, maxdepth);
- }
- else
- maxdepth = btMax(maxdepth, depth);
- }
- //
- static DBVT_INLINE void deletenode(btDbvt* pdbvt,
- btDbvtNode* node)
- {
- btAlignedFree(pdbvt->m_free);
- pdbvt->m_free = node;
- }
- //
- static void recursedeletenode(btDbvt* pdbvt,
- btDbvtNode* node)
- {
- if (node == 0) return;
- if (!node->isleaf())
- {
- recursedeletenode(pdbvt, node->childs[0]);
- recursedeletenode(pdbvt, node->childs[1]);
- }
- if (node == pdbvt->m_root) pdbvt->m_root = 0;
- deletenode(pdbvt, node);
- }
- //
- static DBVT_INLINE btDbvtNode* createnode(btDbvt* pdbvt,
- btDbvtNode* parent,
- void* data)
- {
- btDbvtNode* node;
- if (pdbvt->m_free)
- {
- node = pdbvt->m_free;
- pdbvt->m_free = 0;
- }
- else
- {
- node = new (btAlignedAlloc(sizeof(btDbvtNode), 16)) btDbvtNode();
- }
- node->parent = parent;
- node->data = data;
- node->childs[1] = 0;
- return (node);
- }
- //
- static DBVT_INLINE btDbvtNode* createnode(btDbvt* pdbvt,
- btDbvtNode* parent,
- const btDbvtVolume& volume,
- void* data)
- {
- btDbvtNode* node = createnode(pdbvt, parent, data);
- node->volume = volume;
- return (node);
- }
- //
- static DBVT_INLINE btDbvtNode* createnode(btDbvt* pdbvt,
- btDbvtNode* parent,
- const btDbvtVolume& volume0,
- const btDbvtVolume& volume1,
- void* data)
- {
- btDbvtNode* node = createnode(pdbvt, parent, data);
- Merge(volume0, volume1, node->volume);
- return (node);
- }
- //
- static void insertleaf(btDbvt* pdbvt,
- btDbvtNode* root,
- btDbvtNode* leaf)
- {
- if (!pdbvt->m_root)
- {
- pdbvt->m_root = leaf;
- leaf->parent = 0;
- }
- else
- {
- if (!root->isleaf())
- {
- do
- {
- root = root->childs[Select(leaf->volume,
- root->childs[0]->volume,
- root->childs[1]->volume)];
- } while (!root->isleaf());
- }
- btDbvtNode* prev = root->parent;
- btDbvtNode* node = createnode(pdbvt, prev, leaf->volume, root->volume, 0);
- if (prev)
- {
- prev->childs[indexof(root)] = node;
- node->childs[0] = root;
- root->parent = node;
- node->childs[1] = leaf;
- leaf->parent = node;
- do
- {
- if (!prev->volume.Contain(node->volume))
- Merge(prev->childs[0]->volume, prev->childs[1]->volume, prev->volume);
- else
- break;
- node = prev;
- } while (0 != (prev = node->parent));
- }
- else
- {
- node->childs[0] = root;
- root->parent = node;
- node->childs[1] = leaf;
- leaf->parent = node;
- pdbvt->m_root = node;
- }
- }
- }
- //
- static btDbvtNode* removeleaf(btDbvt* pdbvt,
- btDbvtNode* leaf)
- {
- if (leaf == pdbvt->m_root)
- {
- pdbvt->m_root = 0;
- return (0);
- }
- else
- {
- btDbvtNode* parent = leaf->parent;
- btDbvtNode* prev = parent->parent;
- btDbvtNode* sibling = parent->childs[1 - indexof(leaf)];
- if (prev)
- {
- prev->childs[indexof(parent)] = sibling;
- sibling->parent = prev;
- deletenode(pdbvt, parent);
- while (prev)
- {
- const btDbvtVolume pb = prev->volume;
- Merge(prev->childs[0]->volume, prev->childs[1]->volume, prev->volume);
- if (NotEqual(pb, prev->volume))
- {
- prev = prev->parent;
- }
- else
- break;
- }
- return (prev ? prev : pdbvt->m_root);
- }
- else
- {
- pdbvt->m_root = sibling;
- sibling->parent = 0;
- deletenode(pdbvt, parent);
- return (pdbvt->m_root);
- }
- }
- }
- //
- static void fetchleaves(btDbvt* pdbvt,
- btDbvtNode* root,
- tNodeArray& leaves,
- int depth = -1)
- {
- if (root->isinternal() && depth)
- {
- fetchleaves(pdbvt, root->childs[0], leaves, depth - 1);
- fetchleaves(pdbvt, root->childs[1], leaves, depth - 1);
- deletenode(pdbvt, root);
- }
- else
- {
- leaves.push_back(root);
- }
- }
- //
- static bool leftOfAxis(const btDbvtNode* node,
- const btVector3& org,
- const btVector3& axis)
- {
- return btDot(axis, node->volume.Center() - org) <= 0;
- }
- // Partitions leaves such that leaves[0, n) are on the
- // left of axis, and leaves[n, count) are on the right
- // of axis. returns N.
- static int split(btDbvtNode** leaves,
- int count,
- const btVector3& org,
- const btVector3& axis)
- {
- int begin = 0;
- int end = count;
- for (;;)
- {
- while (begin != end && leftOfAxis(leaves[begin], org, axis))
- {
- ++begin;
- }
- if (begin == end)
- {
- break;
- }
- while (begin != end && !leftOfAxis(leaves[end - 1], org, axis))
- {
- --end;
- }
- if (begin == end)
- {
- break;
- }
- // swap out of place nodes
- --end;
- btDbvtNode* temp = leaves[begin];
- leaves[begin] = leaves[end];
- leaves[end] = temp;
- ++begin;
- }
- return begin;
- }
- //
- static btDbvtVolume bounds(btDbvtNode** leaves,
- int count)
- {
- #ifdef BT_USE_SSE
- ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtVolume)]);
- btDbvtVolume* ptr = (btDbvtVolume*)locals;
- btDbvtVolume& volume = *ptr;
- volume = leaves[0]->volume;
- #else
- btDbvtVolume volume = leaves[0]->volume;
- #endif
- for (int i = 1, ni = count; i < ni; ++i)
- {
- Merge(volume, leaves[i]->volume, volume);
- }
- return (volume);
- }
- //
- static void bottomup(btDbvt* pdbvt,
- btDbvtNode** leaves,
- int count)
- {
- while (count > 1)
- {
- btScalar minsize = SIMD_INFINITY;
- int minidx[2] = {-1, -1};
- for (int i = 0; i < count; ++i)
- {
- for (int j = i + 1; j < count; ++j)
- {
- const btScalar sz = size(merge(leaves[i]->volume, leaves[j]->volume));
- if (sz < minsize)
- {
- minsize = sz;
- minidx[0] = i;
- minidx[1] = j;
- }
- }
- }
- btDbvtNode* n[] = {leaves[minidx[0]], leaves[minidx[1]]};
- btDbvtNode* p = createnode(pdbvt, 0, n[0]->volume, n[1]->volume, 0);
- p->childs[0] = n[0];
- p->childs[1] = n[1];
- n[0]->parent = p;
- n[1]->parent = p;
- leaves[minidx[0]] = p;
- leaves[minidx[1]] = leaves[count - 1];
- --count;
- }
- }
- //
- static btDbvtNode* topdown(btDbvt* pdbvt,
- btDbvtNode** leaves,
- int count,
- int bu_treshold)
- {
- static const btVector3 axis[] = {btVector3(1, 0, 0),
- btVector3(0, 1, 0),
- btVector3(0, 0, 1)};
- btAssert(bu_treshold > 2);
- if (count > 1)
- {
- if (count > bu_treshold)
- {
- const btDbvtVolume vol = bounds(leaves, count);
- const btVector3 org = vol.Center();
- int partition;
- int bestaxis = -1;
- int bestmidp = count;
- int splitcount[3][2] = {{0, 0}, {0, 0}, {0, 0}};
- int i;
- for (i = 0; i < count; ++i)
- {
- const btVector3 x = leaves[i]->volume.Center() - org;
- for (int j = 0; j < 3; ++j)
- {
- ++splitcount[j][btDot(x, axis[j]) > 0 ? 1 : 0];
- }
- }
- for (i = 0; i < 3; ++i)
- {
- if ((splitcount[i][0] > 0) && (splitcount[i][1] > 0))
- {
- const int midp = (int)btFabs(btScalar(splitcount[i][0] - splitcount[i][1]));
- if (midp < bestmidp)
- {
- bestaxis = i;
- bestmidp = midp;
- }
- }
- }
- if (bestaxis >= 0)
- {
- partition = split(leaves, count, org, axis[bestaxis]);
- btAssert(partition != 0 && partition != count);
- }
- else
- {
- partition = count / 2 + 1;
- }
- btDbvtNode* node = createnode(pdbvt, 0, vol, 0);
- node->childs[0] = topdown(pdbvt, &leaves[0], partition, bu_treshold);
- node->childs[1] = topdown(pdbvt, &leaves[partition], count - partition, bu_treshold);
- node->childs[0]->parent = node;
- node->childs[1]->parent = node;
- return (node);
- }
- else
- {
- bottomup(pdbvt, leaves, count);
- return (leaves[0]);
- }
- }
- return (leaves[0]);
- }
- //
- static DBVT_INLINE btDbvtNode* sort(btDbvtNode* n, btDbvtNode*& r)
- {
- btDbvtNode* p = n->parent;
- btAssert(n->isinternal());
- if (p > n)
- {
- const int i = indexof(n);
- const int j = 1 - i;
- btDbvtNode* s = p->childs[j];
- btDbvtNode* q = p->parent;
- btAssert(n == p->childs[i]);
- if (q)
- q->childs[indexof(p)] = n;
- else
- r = n;
- s->parent = n;
- p->parent = n;
- n->parent = q;
- p->childs[0] = n->childs[0];
- p->childs[1] = n->childs[1];
- n->childs[0]->parent = p;
- n->childs[1]->parent = p;
- n->childs[i] = p;
- n->childs[j] = s;
- btSwap(p->volume, n->volume);
- return (p);
- }
- return (n);
- }
- #if 0
- static DBVT_INLINE btDbvtNode* walkup(btDbvtNode* n,int count)
- {
- while(n&&(count--)) n=n->parent;
- return(n);
- }
- #endif
- //
- // Api
- //
- //
- btDbvt::btDbvt()
- {
- m_root = 0;
- m_free = 0;
- m_lkhd = -1;
- m_leaves = 0;
- m_opath = 0;
- }
- //
- btDbvt::~btDbvt()
- {
- clear();
- }
- //
- void btDbvt::clear()
- {
- if (m_root)
- recursedeletenode(this, m_root);
- btAlignedFree(m_free);
- m_free = 0;
- m_lkhd = -1;
- m_stkStack.clear();
- m_opath = 0;
- }
- //
- void btDbvt::optimizeBottomUp()
- {
- if (m_root)
- {
- tNodeArray leaves;
- leaves.reserve(m_leaves);
- fetchleaves(this, m_root, leaves);
- bottomup(this, &leaves[0], leaves.size());
- m_root = leaves[0];
- }
- }
- //
- void btDbvt::optimizeTopDown(int bu_treshold)
- {
- if (m_root)
- {
- tNodeArray leaves;
- leaves.reserve(m_leaves);
- fetchleaves(this, m_root, leaves);
- m_root = topdown(this, &leaves[0], leaves.size(), bu_treshold);
- }
- }
- //
- void btDbvt::optimizeIncremental(int passes)
- {
- if (passes < 0) passes = m_leaves;
- if (m_root && (passes > 0))
- {
- do
- {
- btDbvtNode* node = m_root;
- unsigned bit = 0;
- while (node->isinternal())
- {
- node = sort(node, m_root)->childs[(m_opath >> bit) & 1];
- bit = (bit + 1) & (sizeof(unsigned) * 8 - 1);
- }
- update(node);
- ++m_opath;
- } while (--passes);
- }
- }
- //
- btDbvtNode* btDbvt::insert(const btDbvtVolume& volume, void* data)
- {
- btDbvtNode* leaf = createnode(this, 0, volume, data);
- insertleaf(this, m_root, leaf);
- ++m_leaves;
- return (leaf);
- }
- //
- void btDbvt::update(btDbvtNode* leaf, int lookahead)
- {
- btDbvtNode* root = removeleaf(this, leaf);
- if (root)
- {
- if (lookahead >= 0)
- {
- for (int i = 0; (i < lookahead) && root->parent; ++i)
- {
- root = root->parent;
- }
- }
- else
- root = m_root;
- }
- insertleaf(this, root, leaf);
- }
- //
- void btDbvt::update(btDbvtNode* leaf, btDbvtVolume& volume)
- {
- btDbvtNode* root = removeleaf(this, leaf);
- if (root)
- {
- if (m_lkhd >= 0)
- {
- for (int i = 0; (i < m_lkhd) && root->parent; ++i)
- {
- root = root->parent;
- }
- }
- else
- root = m_root;
- }
- leaf->volume = volume;
- insertleaf(this, root, leaf);
- }
- //
- bool btDbvt::update(btDbvtNode* leaf, btDbvtVolume& volume, const btVector3& velocity, btScalar margin)
- {
- if (leaf->volume.Contain(volume)) return (false);
- volume.Expand(btVector3(margin, margin, margin));
- volume.SignedExpand(velocity);
- update(leaf, volume);
- return (true);
- }
- //
- bool btDbvt::update(btDbvtNode* leaf, btDbvtVolume& volume, const btVector3& velocity)
- {
- if (leaf->volume.Contain(volume)) return (false);
- volume.SignedExpand(velocity);
- update(leaf, volume);
- return (true);
- }
- //
- bool btDbvt::update(btDbvtNode* leaf, btDbvtVolume& volume, btScalar margin)
- {
- if (leaf->volume.Contain(volume)) return (false);
- volume.Expand(btVector3(margin, margin, margin));
- update(leaf, volume);
- return (true);
- }
- //
- void btDbvt::remove(btDbvtNode* leaf)
- {
- removeleaf(this, leaf);
- deletenode(this, leaf);
- --m_leaves;
- }
- //
- void btDbvt::write(IWriter* iwriter) const
- {
- btDbvtNodeEnumerator nodes;
- nodes.nodes.reserve(m_leaves * 2);
- enumNodes(m_root, nodes);
- iwriter->Prepare(m_root, nodes.nodes.size());
- for (int i = 0; i < nodes.nodes.size(); ++i)
- {
- const btDbvtNode* n = nodes.nodes[i];
- int p = -1;
- if (n->parent) p = nodes.nodes.findLinearSearch(n->parent);
- if (n->isinternal())
- {
- const int c0 = nodes.nodes.findLinearSearch(n->childs[0]);
- const int c1 = nodes.nodes.findLinearSearch(n->childs[1]);
- iwriter->WriteNode(n, i, p, c0, c1);
- }
- else
- {
- iwriter->WriteLeaf(n, i, p);
- }
- }
- }
- //
- void btDbvt::clone(btDbvt& dest, IClone* iclone) const
- {
- dest.clear();
- if (m_root != 0)
- {
- btAlignedObjectArray<sStkCLN> stack;
- stack.reserve(m_leaves);
- stack.push_back(sStkCLN(m_root, 0));
- do
- {
- const int i = stack.size() - 1;
- const sStkCLN e = stack[i];
- btDbvtNode* n = createnode(&dest, e.parent, e.node->volume, e.node->data);
- stack.pop_back();
- if (e.parent != 0)
- e.parent->childs[i & 1] = n;
- else
- dest.m_root = n;
- if (e.node->isinternal())
- {
- stack.push_back(sStkCLN(e.node->childs[0], n));
- stack.push_back(sStkCLN(e.node->childs[1], n));
- }
- else
- {
- iclone->CloneLeaf(n);
- }
- } while (stack.size() > 0);
- }
- }
- //
- int btDbvt::maxdepth(const btDbvtNode* node)
- {
- int depth = 0;
- if (node) getmaxdepth(node, 1, depth);
- return (depth);
- }
- //
- int btDbvt::countLeaves(const btDbvtNode* node)
- {
- if (node->isinternal())
- return (countLeaves(node->childs[0]) + countLeaves(node->childs[1]));
- else
- return (1);
- }
- //
- void btDbvt::extractLeaves(const btDbvtNode* node, btAlignedObjectArray<const btDbvtNode*>& leaves)
- {
- if (node->isinternal())
- {
- extractLeaves(node->childs[0], leaves);
- extractLeaves(node->childs[1], leaves);
- }
- else
- {
- leaves.push_back(node);
- }
- }
- //
- #if DBVT_ENABLE_BENCHMARK
- #include <stdio.h>
- #include <stdlib.h>
- #include "LinearMath/btQuickProf.h"
- /*
- q6600,2.4ghz
- /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"
- /GF /FD /MT /GS- /Gy /arch:SSE2 /Zc:wchar_t- /Fp"..\..\out\release8\build\libbulletcollision\libbulletcollision.pch"
- /Fo"..\..\out\release8\build\libbulletcollision\\"
- /Fd"..\..\out\release8\build\libbulletcollision\bulletcollision.pdb"
- /W3 /nologo /c /Wp64 /Zi /errorReport:prompt
- Benchmarking dbvt...
- World scale: 100.000000
- Extents base: 1.000000
- Extents range: 4.000000
- Leaves: 8192
- sizeof(btDbvtVolume): 32 bytes
- sizeof(btDbvtNode): 44 bytes
- [1] btDbvtVolume intersections: 3499 ms (-1%)
- [2] btDbvtVolume merges: 1934 ms (0%)
- [3] btDbvt::collideTT: 5485 ms (-21%)
- [4] btDbvt::collideTT self: 2814 ms (-20%)
- [5] btDbvt::collideTT xform: 7379 ms (-1%)
- [6] btDbvt::collideTT xform,self: 7270 ms (-2%)
- [7] btDbvt::rayTest: 6314 ms (0%),(332143 r/s)
- [8] insert/remove: 2093 ms (0%),(1001983 ir/s)
- [9] updates (teleport): 1879 ms (-3%),(1116100 u/s)
- [10] updates (jitter): 1244 ms (-4%),(1685813 u/s)
- [11] optimize (incremental): 2514 ms (0%),(1668000 o/s)
- [12] btDbvtVolume notequal: 3659 ms (0%)
- [13] culling(OCL+fullsort): 2218 ms (0%),(461 t/s)
- [14] culling(OCL+qsort): 3688 ms (5%),(2221 t/s)
- [15] culling(KDOP+qsort): 1139 ms (-1%),(7192 t/s)
- [16] insert/remove batch(256): 5092 ms (0%),(823704 bir/s)
- [17] btDbvtVolume select: 3419 ms (0%)
- */
- struct btDbvtBenchmark
- {
- struct NilPolicy : btDbvt::ICollide
- {
- NilPolicy() : m_pcount(0), m_depth(-SIMD_INFINITY), m_checksort(true) {}
- void Process(const btDbvtNode*, const btDbvtNode*) { ++m_pcount; }
- void Process(const btDbvtNode*) { ++m_pcount; }
- void Process(const btDbvtNode*, btScalar depth)
- {
- ++m_pcount;
- if (m_checksort)
- {
- if (depth >= m_depth)
- m_depth = depth;
- else
- printf("wrong depth: %f (should be >= %f)\r\n", depth, m_depth);
- }
- }
- int m_pcount;
- btScalar m_depth;
- bool m_checksort;
- };
- struct P14 : btDbvt::ICollide
- {
- struct Node
- {
- const btDbvtNode* leaf;
- btScalar depth;
- };
- void Process(const btDbvtNode* leaf, btScalar depth)
- {
- Node n;
- n.leaf = leaf;
- n.depth = depth;
- }
- static int sortfnc(const Node& a, const Node& b)
- {
- if (a.depth < b.depth) return (+1);
- if (a.depth > b.depth) return (-1);
- return (0);
- }
- btAlignedObjectArray<Node> m_nodes;
- };
- struct P15 : btDbvt::ICollide
- {
- struct Node
- {
- const btDbvtNode* leaf;
- btScalar depth;
- };
- void Process(const btDbvtNode* leaf)
- {
- Node n;
- n.leaf = leaf;
- n.depth = dot(leaf->volume.Center(), m_axis);
- }
- static int sortfnc(const Node& a, const Node& b)
- {
- if (a.depth < b.depth) return (+1);
- if (a.depth > b.depth) return (-1);
- return (0);
- }
- btAlignedObjectArray<Node> m_nodes;
- btVector3 m_axis;
- };
- static btScalar RandUnit()
- {
- return (rand() / (btScalar)RAND_MAX);
- }
- static btVector3 RandVector3()
- {
- return (btVector3(RandUnit(), RandUnit(), RandUnit()));
- }
- static btVector3 RandVector3(btScalar cs)
- {
- return (RandVector3() * cs - btVector3(cs, cs, cs) / 2);
- }
- static btDbvtVolume RandVolume(btScalar cs, btScalar eb, btScalar es)
- {
- return (btDbvtVolume::FromCE(RandVector3(cs), btVector3(eb, eb, eb) + RandVector3() * es));
- }
- static btTransform RandTransform(btScalar cs)
- {
- btTransform t;
- t.setOrigin(RandVector3(cs));
- t.setRotation(btQuaternion(RandUnit() * SIMD_PI * 2, RandUnit() * SIMD_PI * 2, RandUnit() * SIMD_PI * 2).normalized());
- return (t);
- }
- static void RandTree(btScalar cs, btScalar eb, btScalar es, int leaves, btDbvt& dbvt)
- {
- dbvt.clear();
- for (int i = 0; i < leaves; ++i)
- {
- dbvt.insert(RandVolume(cs, eb, es), 0);
- }
- }
- };
- void btDbvt::benchmark()
- {
- static const btScalar cfgVolumeCenterScale = 100;
- static const btScalar cfgVolumeExentsBase = 1;
- static const btScalar cfgVolumeExentsScale = 4;
- static const int cfgLeaves = 8192;
- static const bool cfgEnable = true;
- //[1] btDbvtVolume intersections
- bool cfgBenchmark1_Enable = cfgEnable;
- static const int cfgBenchmark1_Iterations = 8;
- static const int cfgBenchmark1_Reference = 3499;
- //[2] btDbvtVolume merges
- bool cfgBenchmark2_Enable = cfgEnable;
- static const int cfgBenchmark2_Iterations = 4;
- static const int cfgBenchmark2_Reference = 1945;
- //[3] btDbvt::collideTT
- bool cfgBenchmark3_Enable = cfgEnable;
- static const int cfgBenchmark3_Iterations = 512;
- static const int cfgBenchmark3_Reference = 5485;
- //[4] btDbvt::collideTT self
- bool cfgBenchmark4_Enable = cfgEnable;
- static const int cfgBenchmark4_Iterations = 512;
- static const int cfgBenchmark4_Reference = 2814;
- //[5] btDbvt::collideTT xform
- bool cfgBenchmark5_Enable = cfgEnable;
- static const int cfgBenchmark5_Iterations = 512;
- static const btScalar cfgBenchmark5_OffsetScale = 2;
- static const int cfgBenchmark5_Reference = 7379;
- //[6] btDbvt::collideTT xform,self
- bool cfgBenchmark6_Enable = cfgEnable;
- static const int cfgBenchmark6_Iterations = 512;
- static const btScalar cfgBenchmark6_OffsetScale = 2;
- static const int cfgBenchmark6_Reference = 7270;
- //[7] btDbvt::rayTest
- bool cfgBenchmark7_Enable = cfgEnable;
- static const int cfgBenchmark7_Passes = 32;
- static const int cfgBenchmark7_Iterations = 65536;
- static const int cfgBenchmark7_Reference = 6307;
- //[8] insert/remove
- bool cfgBenchmark8_Enable = cfgEnable;
- static const int cfgBenchmark8_Passes = 32;
- static const int cfgBenchmark8_Iterations = 65536;
- static const int cfgBenchmark8_Reference = 2105;
- //[9] updates (teleport)
- bool cfgBenchmark9_Enable = cfgEnable;
- static const int cfgBenchmark9_Passes = 32;
- static const int cfgBenchmark9_Iterations = 65536;
- static const int cfgBenchmark9_Reference = 1879;
- //[10] updates (jitter)
- bool cfgBenchmark10_Enable = cfgEnable;
- static const btScalar cfgBenchmark10_Scale = cfgVolumeCenterScale / 10000;
- static const int cfgBenchmark10_Passes = 32;
- static const int cfgBenchmark10_Iterations = 65536;
- static const int cfgBenchmark10_Reference = 1244;
- //[11] optimize (incremental)
- bool cfgBenchmark11_Enable = cfgEnable;
- static const int cfgBenchmark11_Passes = 64;
- static const int cfgBenchmark11_Iterations = 65536;
- static const int cfgBenchmark11_Reference = 2510;
- //[12] btDbvtVolume notequal
- bool cfgBenchmark12_Enable = cfgEnable;
- static const int cfgBenchmark12_Iterations = 32;
- static const int cfgBenchmark12_Reference = 3677;
- //[13] culling(OCL+fullsort)
- bool cfgBenchmark13_Enable = cfgEnable;
- static const int cfgBenchmark13_Iterations = 1024;
- static const int cfgBenchmark13_Reference = 2231;
- //[14] culling(OCL+qsort)
- bool cfgBenchmark14_Enable = cfgEnable;
- static const int cfgBenchmark14_Iterations = 8192;
- static const int cfgBenchmark14_Reference = 3500;
- //[15] culling(KDOP+qsort)
- bool cfgBenchmark15_Enable = cfgEnable;
- static const int cfgBenchmark15_Iterations = 8192;
- static const int cfgBenchmark15_Reference = 1151;
- //[16] insert/remove batch
- bool cfgBenchmark16_Enable = cfgEnable;
- static const int cfgBenchmark16_BatchCount = 256;
- static const int cfgBenchmark16_Passes = 16384;
- static const int cfgBenchmark16_Reference = 5138;
- //[17] select
- bool cfgBenchmark17_Enable = cfgEnable;
- static const int cfgBenchmark17_Iterations = 4;
- static const int cfgBenchmark17_Reference = 3390;
- btClock wallclock;
- printf("Benchmarking dbvt...\r\n");
- printf("\tWorld scale: %f\r\n", cfgVolumeCenterScale);
- printf("\tExtents base: %f\r\n", cfgVolumeExentsBase);
- printf("\tExtents range: %f\r\n", cfgVolumeExentsScale);
- printf("\tLeaves: %u\r\n", cfgLeaves);
- printf("\tsizeof(btDbvtVolume): %u bytes\r\n", sizeof(btDbvtVolume));
- printf("\tsizeof(btDbvtNode): %u bytes\r\n", sizeof(btDbvtNode));
- if (cfgBenchmark1_Enable)
- { // Benchmark 1
- srand(380843);
- btAlignedObjectArray<btDbvtVolume> volumes;
- btAlignedObjectArray<bool> results;
- volumes.resize(cfgLeaves);
- results.resize(cfgLeaves);
- for (int i = 0; i < cfgLeaves; ++i)
- {
- volumes[i] = btDbvtBenchmark::RandVolume(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale);
- }
- printf("[1] btDbvtVolume intersections: ");
- wallclock.reset();
- for (int i = 0; i < cfgBenchmark1_Iterations; ++i)
- {
- for (int j = 0; j < cfgLeaves; ++j)
- {
- for (int k = 0; k < cfgLeaves; ++k)
- {
- results[k] = Intersect(volumes[j], volumes[k]);
- }
- }
- }
- const int time = (int)wallclock.getTimeMilliseconds();
- printf("%u ms (%i%%)\r\n", time, (time - cfgBenchmark1_Reference) * 100 / time);
- }
- if (cfgBenchmark2_Enable)
- { // Benchmark 2
- srand(380843);
- btAlignedObjectArray<btDbvtVolume> volumes;
- btAlignedObjectArray<btDbvtVolume> results;
- volumes.resize(cfgLeaves);
- results.resize(cfgLeaves);
- for (int i = 0; i < cfgLeaves; ++i)
- {
- volumes[i] = btDbvtBenchmark::RandVolume(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale);
- }
- printf("[2] btDbvtVolume merges: ");
- wallclock.reset();
- for (int i = 0; i < cfgBenchmark2_Iterations; ++i)
- {
- for (int j = 0; j < cfgLeaves; ++j)
- {
- for (int k = 0; k < cfgLeaves; ++k)
- {
- Merge(volumes[j], volumes[k], results[k]);
- }
- }
- }
- const int time = (int)wallclock.getTimeMilliseconds();
- printf("%u ms (%i%%)\r\n", time, (time - cfgBenchmark2_Reference) * 100 / time);
- }
- if (cfgBenchmark3_Enable)
- { // Benchmark 3
- srand(380843);
- btDbvt dbvt[2];
- btDbvtBenchmark::NilPolicy policy;
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt[0]);
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt[1]);
- dbvt[0].optimizeTopDown();
- dbvt[1].optimizeTopDown();
- printf("[3] btDbvt::collideTT: ");
- wallclock.reset();
- for (int i = 0; i < cfgBenchmark3_Iterations; ++i)
- {
- btDbvt::collideTT(dbvt[0].m_root, dbvt[1].m_root, policy);
- }
- const int time = (int)wallclock.getTimeMilliseconds();
- printf("%u ms (%i%%)\r\n", time, (time - cfgBenchmark3_Reference) * 100 / time);
- }
- if (cfgBenchmark4_Enable)
- { // Benchmark 4
- srand(380843);
- btDbvt dbvt;
- btDbvtBenchmark::NilPolicy policy;
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
- dbvt.optimizeTopDown();
- printf("[4] btDbvt::collideTT self: ");
- wallclock.reset();
- for (int i = 0; i < cfgBenchmark4_Iterations; ++i)
- {
- btDbvt::collideTT(dbvt.m_root, dbvt.m_root, policy);
- }
- const int time = (int)wallclock.getTimeMilliseconds();
- printf("%u ms (%i%%)\r\n", time, (time - cfgBenchmark4_Reference) * 100 / time);
- }
- if (cfgBenchmark5_Enable)
- { // Benchmark 5
- srand(380843);
- btDbvt dbvt[2];
- btAlignedObjectArray<btTransform> transforms;
- btDbvtBenchmark::NilPolicy policy;
- transforms.resize(cfgBenchmark5_Iterations);
- for (int i = 0; i < transforms.size(); ++i)
- {
- transforms[i] = btDbvtBenchmark::RandTransform(cfgVolumeCenterScale * cfgBenchmark5_OffsetScale);
- }
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt[0]);
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt[1]);
- dbvt[0].optimizeTopDown();
- dbvt[1].optimizeTopDown();
- printf("[5] btDbvt::collideTT xform: ");
- wallclock.reset();
- for (int i = 0; i < cfgBenchmark5_Iterations; ++i)
- {
- btDbvt::collideTT(dbvt[0].m_root, dbvt[1].m_root, transforms[i], policy);
- }
- const int time = (int)wallclock.getTimeMilliseconds();
- printf("%u ms (%i%%)\r\n", time, (time - cfgBenchmark5_Reference) * 100 / time);
- }
- if (cfgBenchmark6_Enable)
- { // Benchmark 6
- srand(380843);
- btDbvt dbvt;
- btAlignedObjectArray<btTransform> transforms;
- btDbvtBenchmark::NilPolicy policy;
- transforms.resize(cfgBenchmark6_Iterations);
- for (int i = 0; i < transforms.size(); ++i)
- {
- transforms[i] = btDbvtBenchmark::RandTransform(cfgVolumeCenterScale * cfgBenchmark6_OffsetScale);
- }
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
- dbvt.optimizeTopDown();
- printf("[6] btDbvt::collideTT xform,self: ");
- wallclock.reset();
- for (int i = 0; i < cfgBenchmark6_Iterations; ++i)
- {
- btDbvt::collideTT(dbvt.m_root, dbvt.m_root, transforms[i], policy);
- }
- const int time = (int)wallclock.getTimeMilliseconds();
- printf("%u ms (%i%%)\r\n", time, (time - cfgBenchmark6_Reference) * 100 / time);
- }
- if (cfgBenchmark7_Enable)
- { // Benchmark 7
- srand(380843);
- btDbvt dbvt;
- btAlignedObjectArray<btVector3> rayorg;
- btAlignedObjectArray<btVector3> raydir;
- btDbvtBenchmark::NilPolicy policy;
- rayorg.resize(cfgBenchmark7_Iterations);
- raydir.resize(cfgBenchmark7_Iterations);
- for (int i = 0; i < rayorg.size(); ++i)
- {
- rayorg[i] = btDbvtBenchmark::RandVector3(cfgVolumeCenterScale * 2);
- raydir[i] = btDbvtBenchmark::RandVector3(cfgVolumeCenterScale * 2);
- }
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
- dbvt.optimizeTopDown();
- printf("[7] btDbvt::rayTest: ");
- wallclock.reset();
- for (int i = 0; i < cfgBenchmark7_Passes; ++i)
- {
- for (int j = 0; j < cfgBenchmark7_Iterations; ++j)
- {
- btDbvt::rayTest(dbvt.m_root, rayorg[j], rayorg[j] + raydir[j], policy);
- }
- }
- const int time = (int)wallclock.getTimeMilliseconds();
- unsigned rays = cfgBenchmark7_Passes * cfgBenchmark7_Iterations;
- printf("%u ms (%i%%),(%u r/s)\r\n", time, (time - cfgBenchmark7_Reference) * 100 / time, (rays * 1000) / time);
- }
- if (cfgBenchmark8_Enable)
- { // Benchmark 8
- srand(380843);
- btDbvt dbvt;
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
- dbvt.optimizeTopDown();
- printf("[8] insert/remove: ");
- wallclock.reset();
- for (int i = 0; i < cfgBenchmark8_Passes; ++i)
- {
- for (int j = 0; j < cfgBenchmark8_Iterations; ++j)
- {
- dbvt.remove(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale), 0));
- }
- }
- const int time = (int)wallclock.getTimeMilliseconds();
- const int ir = cfgBenchmark8_Passes * cfgBenchmark8_Iterations;
- printf("%u ms (%i%%),(%u ir/s)\r\n", time, (time - cfgBenchmark8_Reference) * 100 / time, ir * 1000 / time);
- }
- if (cfgBenchmark9_Enable)
- { // Benchmark 9
- srand(380843);
- btDbvt dbvt;
- btAlignedObjectArray<const btDbvtNode*> leaves;
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
- dbvt.optimizeTopDown();
- dbvt.extractLeaves(dbvt.m_root, leaves);
- printf("[9] updates (teleport): ");
- wallclock.reset();
- for (int i = 0; i < cfgBenchmark9_Passes; ++i)
- {
- for (int j = 0; j < cfgBenchmark9_Iterations; ++j)
- {
- dbvt.update(const_cast<btDbvtNode*>(leaves[rand() % cfgLeaves]),
- btDbvtBenchmark::RandVolume(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale));
- }
- }
- const int time = (int)wallclock.getTimeMilliseconds();
- const int up = cfgBenchmark9_Passes * cfgBenchmark9_Iterations;
- printf("%u ms (%i%%),(%u u/s)\r\n", time, (time - cfgBenchmark9_Reference) * 100 / time, up * 1000 / time);
- }
- if (cfgBenchmark10_Enable)
- { // Benchmark 10
- srand(380843);
- btDbvt dbvt;
- btAlignedObjectArray<const btDbvtNode*> leaves;
- btAlignedObjectArray<btVector3> vectors;
- vectors.resize(cfgBenchmark10_Iterations);
- for (int i = 0; i < vectors.size(); ++i)
- {
- vectors[i] = (btDbvtBenchmark::RandVector3() * 2 - btVector3(1, 1, 1)) * cfgBenchmark10_Scale;
- }
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
- dbvt.optimizeTopDown();
- dbvt.extractLeaves(dbvt.m_root, leaves);
- printf("[10] updates (jitter): ");
- wallclock.reset();
- for (int i = 0; i < cfgBenchmark10_Passes; ++i)
- {
- for (int j = 0; j < cfgBenchmark10_Iterations; ++j)
- {
- const btVector3& d = vectors[j];
- btDbvtNode* l = const_cast<btDbvtNode*>(leaves[rand() % cfgLeaves]);
- btDbvtVolume v = btDbvtVolume::FromMM(l->volume.Mins() + d, l->volume.Maxs() + d);
- dbvt.update(l, v);
- }
- }
- const int time = (int)wallclock.getTimeMilliseconds();
- const int up = cfgBenchmark10_Passes * cfgBenchmark10_Iterations;
- printf("%u ms (%i%%),(%u u/s)\r\n", time, (time - cfgBenchmark10_Reference) * 100 / time, up * 1000 / time);
- }
- if (cfgBenchmark11_Enable)
- { // Benchmark 11
- srand(380843);
- btDbvt dbvt;
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
- dbvt.optimizeTopDown();
- printf("[11] optimize (incremental): ");
- wallclock.reset();
- for (int i = 0; i < cfgBenchmark11_Passes; ++i)
- {
- dbvt.optimizeIncremental(cfgBenchmark11_Iterations);
- }
- const int time = (int)wallclock.getTimeMilliseconds();
- const int op = cfgBenchmark11_Passes * cfgBenchmark11_Iterations;
- printf("%u ms (%i%%),(%u o/s)\r\n", time, (time - cfgBenchmark11_Reference) * 100 / time, op / time * 1000);
- }
- if (cfgBenchmark12_Enable)
- { // Benchmark 12
- srand(380843);
- btAlignedObjectArray<btDbvtVolume> volumes;
- btAlignedObjectArray<bool> results;
- volumes.resize(cfgLeaves);
- results.resize(cfgLeaves);
- for (int i = 0; i < cfgLeaves; ++i)
- {
- volumes[i] = btDbvtBenchmark::RandVolume(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale);
- }
- printf("[12] btDbvtVolume notequal: ");
- wallclock.reset();
- for (int i = 0; i < cfgBenchmark12_Iterations; ++i)
- {
- for (int j = 0; j < cfgLeaves; ++j)
- {
- for (int k = 0; k < cfgLeaves; ++k)
- {
- results[k] = NotEqual(volumes[j], volumes[k]);
- }
- }
- }
- const int time = (int)wallclock.getTimeMilliseconds();
- printf("%u ms (%i%%)\r\n", time, (time - cfgBenchmark12_Reference) * 100 / time);
- }
- if (cfgBenchmark13_Enable)
- { // Benchmark 13
- srand(380843);
- btDbvt dbvt;
- btAlignedObjectArray<btVector3> vectors;
- btDbvtBenchmark::NilPolicy policy;
- vectors.resize(cfgBenchmark13_Iterations);
- for (int i = 0; i < vectors.size(); ++i)
- {
- vectors[i] = (btDbvtBenchmark::RandVector3() * 2 - btVector3(1, 1, 1)).normalized();
- }
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
- dbvt.optimizeTopDown();
- printf("[13] culling(OCL+fullsort): ");
- wallclock.reset();
- for (int i = 0; i < cfgBenchmark13_Iterations; ++i)
- {
- static const btScalar offset = 0;
- policy.m_depth = -SIMD_INFINITY;
- dbvt.collideOCL(dbvt.m_root, &vectors[i], &offset, vectors[i], 1, policy);
- }
- const int time = (int)wallclock.getTimeMilliseconds();
- const int t = cfgBenchmark13_Iterations;
- printf("%u ms (%i%%),(%u t/s)\r\n", time, (time - cfgBenchmark13_Reference) * 100 / time, (t * 1000) / time);
- }
- if (cfgBenchmark14_Enable)
- { // Benchmark 14
- srand(380843);
- btDbvt dbvt;
- btAlignedObjectArray<btVector3> vectors;
- btDbvtBenchmark::P14 policy;
- vectors.resize(cfgBenchmark14_Iterations);
- for (int i = 0; i < vectors.size(); ++i)
- {
- vectors[i] = (btDbvtBenchmark::RandVector3() * 2 - btVector3(1, 1, 1)).normalized();
- }
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
- dbvt.optimizeTopDown();
- policy.m_nodes.reserve(cfgLeaves);
- printf("[14] culling(OCL+qsort): ");
- wallclock.reset();
- for (int i = 0; i < cfgBenchmark14_Iterations; ++i)
- {
- static const btScalar offset = 0;
- policy.m_nodes.resize(0);
- dbvt.collideOCL(dbvt.m_root, &vectors[i], &offset, vectors[i], 1, policy, false);
- policy.m_nodes.quickSort(btDbvtBenchmark::P14::sortfnc);
- }
- const int time = (int)wallclock.getTimeMilliseconds();
- const int t = cfgBenchmark14_Iterations;
- printf("%u ms (%i%%),(%u t/s)\r\n", time, (time - cfgBenchmark14_Reference) * 100 / time, (t * 1000) / time);
- }
- if (cfgBenchmark15_Enable)
- { // Benchmark 15
- srand(380843);
- btDbvt dbvt;
- btAlignedObjectArray<btVector3> vectors;
- btDbvtBenchmark::P15 policy;
- vectors.resize(cfgBenchmark15_Iterations);
- for (int i = 0; i < vectors.size(); ++i)
- {
- vectors[i] = (btDbvtBenchmark::RandVector3() * 2 - btVector3(1, 1, 1)).normalized();
- }
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
- dbvt.optimizeTopDown();
- policy.m_nodes.reserve(cfgLeaves);
- printf("[15] culling(KDOP+qsort): ");
- wallclock.reset();
- for (int i = 0; i < cfgBenchmark15_Iterations; ++i)
- {
- static const btScalar offset = 0;
- policy.m_nodes.resize(0);
- policy.m_axis = vectors[i];
- dbvt.collideKDOP(dbvt.m_root, &vectors[i], &offset, 1, policy);
- policy.m_nodes.quickSort(btDbvtBenchmark::P15::sortfnc);
- }
- const int time = (int)wallclock.getTimeMilliseconds();
- const int t = cfgBenchmark15_Iterations;
- printf("%u ms (%i%%),(%u t/s)\r\n", time, (time - cfgBenchmark15_Reference) * 100 / time, (t * 1000) / time);
- }
- if (cfgBenchmark16_Enable)
- { // Benchmark 16
- srand(380843);
- btDbvt dbvt;
- btAlignedObjectArray<btDbvtNode*> batch;
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
- dbvt.optimizeTopDown();
- batch.reserve(cfgBenchmark16_BatchCount);
- printf("[16] insert/remove batch(%u): ", cfgBenchmark16_BatchCount);
- wallclock.reset();
- for (int i = 0; i < cfgBenchmark16_Passes; ++i)
- {
- for (int j = 0; j < cfgBenchmark16_BatchCount; ++j)
- {
- batch.push_back(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale), 0));
- }
- for (int j = 0; j < cfgBenchmark16_BatchCount; ++j)
- {
- dbvt.remove(batch[j]);
- }
- batch.resize(0);
- }
- const int time = (int)wallclock.getTimeMilliseconds();
- const int ir = cfgBenchmark16_Passes * cfgBenchmark16_BatchCount;
- printf("%u ms (%i%%),(%u bir/s)\r\n", time, (time - cfgBenchmark16_Reference) * 100 / time, int(ir * 1000.0 / time));
- }
- if (cfgBenchmark17_Enable)
- { // Benchmark 17
- srand(380843);
- btAlignedObjectArray<btDbvtVolume> volumes;
- btAlignedObjectArray<int> results;
- btAlignedObjectArray<int> indices;
- volumes.resize(cfgLeaves);
- results.resize(cfgLeaves);
- indices.resize(cfgLeaves);
- for (int i = 0; i < cfgLeaves; ++i)
- {
- indices[i] = i;
- volumes[i] = btDbvtBenchmark::RandVolume(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale);
- }
- for (int i = 0; i < cfgLeaves; ++i)
- {
- btSwap(indices[i], indices[rand() % cfgLeaves]);
- }
- printf("[17] btDbvtVolume select: ");
- wallclock.reset();
- for (int i = 0; i < cfgBenchmark17_Iterations; ++i)
- {
- for (int j = 0; j < cfgLeaves; ++j)
- {
- for (int k = 0; k < cfgLeaves; ++k)
- {
- const int idx = indices[k];
- results[idx] = Select(volumes[idx], volumes[j], volumes[k]);
- }
- }
- }
- const int time = (int)wallclock.getTimeMilliseconds();
- printf("%u ms (%i%%)\r\n", time, (time - cfgBenchmark17_Reference) * 100 / time);
- }
- printf("\r\n\r\n");
- }
- #endif
|