55 return (edges.
x() * edges.
y() * edges.
z() +
56 edges.
x() + edges.
y() + edges.
z());
68 maxdepth =
btMax(maxdepth, depth);
83 if (node == 0)
return;
156 }
while (!root->
isleaf());
174 }
while (0 != (prev = node->
parent));
191 if (leaf == pdbvt->
m_root)
217 return (prev ? prev : pdbvt->
m_root);
267 while (begin != end &&
leftOfAxis(leaves[begin], org, axis))
277 while (begin != end && !
leftOfAxis(leaves[end - 1], org, axis))
290 leaves[begin] = leaves[end];
306 volume = leaves[0]->
volume;
310 for (
int i = 1, ni = count; i < ni; ++i)
312 Merge(volume, leaves[i]->volume, volume);
325 int minidx[2] = {-1, -1};
326 for (
int i = 0; i < count; ++i)
328 for (
int j = i + 1; j < count; ++j)
339 btDbvtNode* n[] = {leaves[minidx[0]], leaves[minidx[1]]};
345 leaves[minidx[0]] = p;
346 leaves[minidx[1]] = leaves[count - 1];
363 if (count > bu_treshold)
369 int bestmidp = count;
370 int splitcount[3][2] = {{0, 0}, {0, 0}, {0, 0}};
372 for (i = 0; i < count; ++i)
375 for (
int j = 0; j < 3; ++j)
377 ++splitcount[j][
btDot(x, axis[j]) > 0 ? 1 : 0];
380 for (i = 0; i < 3; ++i)
382 if ((splitcount[i][0] > 0) && (splitcount[i][1] > 0))
384 const int midp = (int)
btFabs(
btScalar(splitcount[i][0] - splitcount[i][1]));
394 partition =
split(leaves, count, org, axis[bestaxis]);
395 btAssert(partition != 0 && partition != count);
399 partition = count / 2 + 1;
402 node->
childs[0] =
topdown(pdbvt, &leaves[0], partition, bu_treshold);
403 node->
childs[1] =
topdown(pdbvt, &leaves[partition], count - partition, bu_treshold);
451 while(n&&(count--)) n=n->
parent;
517 if (
m_root && (passes > 0))
526 bit = (bit + 1) & (
sizeof(
unsigned) * 8 - 1);
551 for (
int i = 0; (i < lookahead) && root->
parent; ++i)
625 for (
int i = 0; i < nodes.
nodes.
size(); ++i)
654 const int i = stack.
size() - 1;
671 }
while (stack.
size() > 0);
707 #if DBVT_ENABLE_BENCHMARK
711 #include "LinearMath/btQuickProf.h"
748 struct btDbvtBenchmark
752 NilPolicy() : m_pcount(0), m_depth(-
SIMD_INFINITY), m_checksort(true) {}
754 void Process(
const btDbvtNode*) { ++m_pcount; }
760 if (depth >= m_depth)
763 printf(
"wrong depth: %f (should be >= %f)\r\n", depth, m_depth);
783 static int sortfnc(
const Node& a,
const Node& b)
785 if (a.depth < b.depth)
return (+1);
786 if (a.depth > b.depth)
return (-1);
804 static int sortfnc(
const Node& a,
const Node& b)
806 if (a.depth < b.depth)
return (+1);
807 if (a.depth > b.depth)
return (-1);
815 return (rand() / (
btScalar)RAND_MAX);
819 return (
btVector3(RandUnit(), RandUnit(), RandUnit()));
823 return (RandVector3() * cs -
btVector3(cs, cs, cs) / 2);
839 for (
int i = 0; i < leaves; ++i)
841 dbvt.
insert(RandVolume(cs, eb, es), 0);
848 static const btScalar cfgVolumeCenterScale = 100;
849 static const btScalar cfgVolumeExentsBase = 1;
850 static const btScalar cfgVolumeExentsScale = 4;
851 static const int cfgLeaves = 8192;
852 static const bool cfgEnable =
true;
855 bool cfgBenchmark1_Enable = cfgEnable;
856 static const int cfgBenchmark1_Iterations = 8;
857 static const int cfgBenchmark1_Reference = 3499;
859 bool cfgBenchmark2_Enable = cfgEnable;
860 static const int cfgBenchmark2_Iterations = 4;
861 static const int cfgBenchmark2_Reference = 1945;
863 bool cfgBenchmark3_Enable = cfgEnable;
864 static const int cfgBenchmark3_Iterations = 512;
865 static const int cfgBenchmark3_Reference = 5485;
867 bool cfgBenchmark4_Enable = cfgEnable;
868 static const int cfgBenchmark4_Iterations = 512;
869 static const int cfgBenchmark4_Reference = 2814;
871 bool cfgBenchmark5_Enable = cfgEnable;
872 static const int cfgBenchmark5_Iterations = 512;
873 static const btScalar cfgBenchmark5_OffsetScale = 2;
874 static const int cfgBenchmark5_Reference = 7379;
876 bool cfgBenchmark6_Enable = cfgEnable;
877 static const int cfgBenchmark6_Iterations = 512;
878 static const btScalar cfgBenchmark6_OffsetScale = 2;
879 static const int cfgBenchmark6_Reference = 7270;
881 bool cfgBenchmark7_Enable = cfgEnable;
882 static const int cfgBenchmark7_Passes = 32;
883 static const int cfgBenchmark7_Iterations = 65536;
884 static const int cfgBenchmark7_Reference = 6307;
886 bool cfgBenchmark8_Enable = cfgEnable;
887 static const int cfgBenchmark8_Passes = 32;
888 static const int cfgBenchmark8_Iterations = 65536;
889 static const int cfgBenchmark8_Reference = 2105;
891 bool cfgBenchmark9_Enable = cfgEnable;
892 static const int cfgBenchmark9_Passes = 32;
893 static const int cfgBenchmark9_Iterations = 65536;
894 static const int cfgBenchmark9_Reference = 1879;
896 bool cfgBenchmark10_Enable = cfgEnable;
897 static const btScalar cfgBenchmark10_Scale = cfgVolumeCenterScale / 10000;
898 static const int cfgBenchmark10_Passes = 32;
899 static const int cfgBenchmark10_Iterations = 65536;
900 static const int cfgBenchmark10_Reference = 1244;
902 bool cfgBenchmark11_Enable = cfgEnable;
903 static const int cfgBenchmark11_Passes = 64;
904 static const int cfgBenchmark11_Iterations = 65536;
905 static const int cfgBenchmark11_Reference = 2510;
907 bool cfgBenchmark12_Enable = cfgEnable;
908 static const int cfgBenchmark12_Iterations = 32;
909 static const int cfgBenchmark12_Reference = 3677;
911 bool cfgBenchmark13_Enable = cfgEnable;
912 static const int cfgBenchmark13_Iterations = 1024;
913 static const int cfgBenchmark13_Reference = 2231;
915 bool cfgBenchmark14_Enable = cfgEnable;
916 static const int cfgBenchmark14_Iterations = 8192;
917 static const int cfgBenchmark14_Reference = 3500;
919 bool cfgBenchmark15_Enable = cfgEnable;
920 static const int cfgBenchmark15_Iterations = 8192;
921 static const int cfgBenchmark15_Reference = 1151;
923 bool cfgBenchmark16_Enable = cfgEnable;
924 static const int cfgBenchmark16_BatchCount = 256;
925 static const int cfgBenchmark16_Passes = 16384;
926 static const int cfgBenchmark16_Reference = 5138;
928 bool cfgBenchmark17_Enable = cfgEnable;
929 static const int cfgBenchmark17_Iterations = 4;
930 static const int cfgBenchmark17_Reference = 3390;
933 printf(
"Benchmarking dbvt...\r\n");
934 printf(
"\tWorld scale: %f\r\n", cfgVolumeCenterScale);
935 printf(
"\tExtents base: %f\r\n", cfgVolumeExentsBase);
936 printf(
"\tExtents range: %f\r\n", cfgVolumeExentsScale);
937 printf(
"\tLeaves: %u\r\n", cfgLeaves);
938 printf(
"\tsizeof(btDbvtVolume): %u bytes\r\n",
sizeof(
btDbvtVolume));
939 printf(
"\tsizeof(btDbvtNode): %u bytes\r\n",
sizeof(
btDbvtNode));
940 if (cfgBenchmark1_Enable)
945 volumes.
resize(cfgLeaves);
946 results.
resize(cfgLeaves);
947 for (
int i = 0; i < cfgLeaves; ++i)
949 volumes[i] = btDbvtBenchmark::RandVolume(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale);
951 printf(
"[1] btDbvtVolume intersections: ");
953 for (
int i = 0; i < cfgBenchmark1_Iterations; ++i)
955 for (
int j = 0; j < cfgLeaves; ++j)
957 for (
int k = 0; k < cfgLeaves; ++k)
959 results[k] =
Intersect(volumes[j], volumes[k]);
964 printf(
"%u ms (%i%%)\r\n", time, (time - cfgBenchmark1_Reference) * 100 / time);
966 if (cfgBenchmark2_Enable)
971 volumes.
resize(cfgLeaves);
972 results.
resize(cfgLeaves);
973 for (
int i = 0; i < cfgLeaves; ++i)
975 volumes[i] = btDbvtBenchmark::RandVolume(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale);
977 printf(
"[2] btDbvtVolume merges: ");
979 for (
int i = 0; i < cfgBenchmark2_Iterations; ++i)
981 for (
int j = 0; j < cfgLeaves; ++j)
983 for (
int k = 0; k < cfgLeaves; ++k)
985 Merge(volumes[j], volumes[k], results[k]);
990 printf(
"%u ms (%i%%)\r\n", time, (time - cfgBenchmark2_Reference) * 100 / time);
992 if (cfgBenchmark3_Enable)
996 btDbvtBenchmark::NilPolicy policy;
997 btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt[0]);
998 btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt[1]);
1001 printf(
"[3] btDbvt::collideTT: ");
1003 for (
int i = 0; i < cfgBenchmark3_Iterations; ++i)
1008 printf(
"%u ms (%i%%)\r\n", time, (time - cfgBenchmark3_Reference) * 100 / time);
1010 if (cfgBenchmark4_Enable)
1014 btDbvtBenchmark::NilPolicy policy;
1015 btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
1017 printf(
"[4] btDbvt::collideTT self: ");
1019 for (
int i = 0; i < cfgBenchmark4_Iterations; ++i)
1024 printf(
"%u ms (%i%%)\r\n", time, (time - cfgBenchmark4_Reference) * 100 / time);
1026 if (cfgBenchmark5_Enable)
1031 btDbvtBenchmark::NilPolicy policy;
1032 transforms.
resize(cfgBenchmark5_Iterations);
1033 for (
int i = 0; i < transforms.
size(); ++i)
1035 transforms[i] = btDbvtBenchmark::RandTransform(cfgVolumeCenterScale * cfgBenchmark5_OffsetScale);
1037 btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt[0]);
1038 btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt[1]);
1041 printf(
"[5] btDbvt::collideTT xform: ");
1043 for (
int i = 0; i < cfgBenchmark5_Iterations; ++i)
1048 printf(
"%u ms (%i%%)\r\n", time, (time - cfgBenchmark5_Reference) * 100 / time);
1050 if (cfgBenchmark6_Enable)
1055 btDbvtBenchmark::NilPolicy policy;
1056 transforms.
resize(cfgBenchmark6_Iterations);
1057 for (
int i = 0; i < transforms.
size(); ++i)
1059 transforms[i] = btDbvtBenchmark::RandTransform(cfgVolumeCenterScale * cfgBenchmark6_OffsetScale);
1061 btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
1063 printf(
"[6] btDbvt::collideTT xform,self: ");
1065 for (
int i = 0; i < cfgBenchmark6_Iterations; ++i)
1070 printf(
"%u ms (%i%%)\r\n", time, (time - cfgBenchmark6_Reference) * 100 / time);
1072 if (cfgBenchmark7_Enable)
1078 btDbvtBenchmark::NilPolicy policy;
1079 rayorg.
resize(cfgBenchmark7_Iterations);
1080 raydir.
resize(cfgBenchmark7_Iterations);
1081 for (
int i = 0; i < rayorg.
size(); ++i)
1083 rayorg[i] = btDbvtBenchmark::RandVector3(cfgVolumeCenterScale * 2);
1084 raydir[i] = btDbvtBenchmark::RandVector3(cfgVolumeCenterScale * 2);
1086 btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
1088 printf(
"[7] btDbvt::rayTest: ");
1090 for (
int i = 0; i < cfgBenchmark7_Passes; ++i)
1092 for (
int j = 0; j < cfgBenchmark7_Iterations; ++j)
1098 unsigned rays = cfgBenchmark7_Passes * cfgBenchmark7_Iterations;
1099 printf(
"%u ms (%i%%),(%u r/s)\r\n", time, (time - cfgBenchmark7_Reference) * 100 / time, (rays * 1000) / time);
1101 if (cfgBenchmark8_Enable)
1105 btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
1107 printf(
"[8] insert/remove: ");
1109 for (
int i = 0; i < cfgBenchmark8_Passes; ++i)
1111 for (
int j = 0; j < cfgBenchmark8_Iterations; ++j)
1113 dbvt.
remove(dbvt.
insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale), 0));
1117 const int ir = cfgBenchmark8_Passes * cfgBenchmark8_Iterations;
1118 printf(
"%u ms (%i%%),(%u ir/s)\r\n", time, (time - cfgBenchmark8_Reference) * 100 / time, ir * 1000 / time);
1120 if (cfgBenchmark9_Enable)
1125 btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
1128 printf(
"[9] updates (teleport): ");
1130 for (
int i = 0; i < cfgBenchmark9_Passes; ++i)
1132 for (
int j = 0; j < cfgBenchmark9_Iterations; ++j)
1134 dbvt.
update(const_cast<btDbvtNode*>(leaves[rand() % cfgLeaves]),
1135 btDbvtBenchmark::RandVolume(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale));
1139 const int up = cfgBenchmark9_Passes * cfgBenchmark9_Iterations;
1140 printf(
"%u ms (%i%%),(%u u/s)\r\n", time, (time - cfgBenchmark9_Reference) * 100 / time, up * 1000 / time);
1142 if (cfgBenchmark10_Enable)
1148 vectors.
resize(cfgBenchmark10_Iterations);
1149 for (
int i = 0; i < vectors.
size(); ++i)
1151 vectors[i] = (btDbvtBenchmark::RandVector3() * 2 -
btVector3(1, 1, 1)) * cfgBenchmark10_Scale;
1153 btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
1156 printf(
"[10] updates (jitter): ");
1159 for (
int i = 0; i < cfgBenchmark10_Passes; ++i)
1161 for (
int j = 0; j < cfgBenchmark10_Iterations; ++j)
1164 btDbvtNode* l = const_cast<btDbvtNode*>(leaves[rand() % cfgLeaves]);
1170 const int up = cfgBenchmark10_Passes * cfgBenchmark10_Iterations;
1171 printf(
"%u ms (%i%%),(%u u/s)\r\n", time, (time - cfgBenchmark10_Reference) * 100 / time, up * 1000 / time);
1173 if (cfgBenchmark11_Enable)
1177 btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
1179 printf(
"[11] optimize (incremental): ");
1181 for (
int i = 0; i < cfgBenchmark11_Passes; ++i)
1186 const int op = cfgBenchmark11_Passes * cfgBenchmark11_Iterations;
1187 printf(
"%u ms (%i%%),(%u o/s)\r\n", time, (time - cfgBenchmark11_Reference) * 100 / time, op / time * 1000);
1189 if (cfgBenchmark12_Enable)
1194 volumes.
resize(cfgLeaves);
1195 results.
resize(cfgLeaves);
1196 for (
int i = 0; i < cfgLeaves; ++i)
1198 volumes[i] = btDbvtBenchmark::RandVolume(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale);
1200 printf(
"[12] btDbvtVolume notequal: ");
1202 for (
int i = 0; i < cfgBenchmark12_Iterations; ++i)
1204 for (
int j = 0; j < cfgLeaves; ++j)
1206 for (
int k = 0; k < cfgLeaves; ++k)
1208 results[k] =
NotEqual(volumes[j], volumes[k]);
1213 printf(
"%u ms (%i%%)\r\n", time, (time - cfgBenchmark12_Reference) * 100 / time);
1215 if (cfgBenchmark13_Enable)
1220 btDbvtBenchmark::NilPolicy policy;
1221 vectors.
resize(cfgBenchmark13_Iterations);
1222 for (
int i = 0; i < vectors.
size(); ++i)
1224 vectors[i] = (btDbvtBenchmark::RandVector3() * 2 -
btVector3(1, 1, 1)).normalized();
1226 btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
1228 printf(
"[13] culling(OCL+fullsort): ");
1230 for (
int i = 0; i < cfgBenchmark13_Iterations; ++i)
1237 const int t = cfgBenchmark13_Iterations;
1238 printf(
"%u ms (%i%%),(%u t/s)\r\n", time, (time - cfgBenchmark13_Reference) * 100 / time, (t * 1000) / time);
1240 if (cfgBenchmark14_Enable)
1245 btDbvtBenchmark::P14 policy;
1246 vectors.
resize(cfgBenchmark14_Iterations);
1247 for (
int i = 0; i < vectors.
size(); ++i)
1249 vectors[i] = (btDbvtBenchmark::RandVector3() * 2 -
btVector3(1, 1, 1)).normalized();
1251 btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
1253 policy.m_nodes.reserve(cfgLeaves);
1254 printf(
"[14] culling(OCL+qsort): ");
1256 for (
int i = 0; i < cfgBenchmark14_Iterations; ++i)
1259 policy.m_nodes.resize(0);
1260 dbvt.
collideOCL(dbvt.
m_root, &vectors[i], &offset, vectors[i], 1, policy,
false);
1261 policy.m_nodes.quickSort(btDbvtBenchmark::P14::sortfnc);
1264 const int t = cfgBenchmark14_Iterations;
1265 printf(
"%u ms (%i%%),(%u t/s)\r\n", time, (time - cfgBenchmark14_Reference) * 100 / time, (t * 1000) / time);
1267 if (cfgBenchmark15_Enable)
1272 btDbvtBenchmark::P15 policy;
1273 vectors.
resize(cfgBenchmark15_Iterations);
1274 for (
int i = 0; i < vectors.
size(); ++i)
1276 vectors[i] = (btDbvtBenchmark::RandVector3() * 2 -
btVector3(1, 1, 1)).normalized();
1278 btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
1280 policy.m_nodes.reserve(cfgLeaves);
1281 printf(
"[15] culling(KDOP+qsort): ");
1283 for (
int i = 0; i < cfgBenchmark15_Iterations; ++i)
1286 policy.m_nodes.resize(0);
1287 policy.m_axis = vectors[i];
1289 policy.m_nodes.quickSort(btDbvtBenchmark::P15::sortfnc);
1292 const int t = cfgBenchmark15_Iterations;
1293 printf(
"%u ms (%i%%),(%u t/s)\r\n", time, (time - cfgBenchmark15_Reference) * 100 / time, (t * 1000) / time);
1295 if (cfgBenchmark16_Enable)
1300 btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt);
1302 batch.
reserve(cfgBenchmark16_BatchCount);
1303 printf(
"[16] insert/remove batch(%u): ", cfgBenchmark16_BatchCount);
1305 for (
int i = 0; i < cfgBenchmark16_Passes; ++i)
1307 for (
int j = 0; j < cfgBenchmark16_BatchCount; ++j)
1309 batch.
push_back(dbvt.
insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale), 0));
1311 for (
int j = 0; j < cfgBenchmark16_BatchCount; ++j)
1318 const int ir = cfgBenchmark16_Passes * cfgBenchmark16_BatchCount;
1319 printf(
"%u ms (%i%%),(%u bir/s)\r\n", time, (time - cfgBenchmark16_Reference) * 100 / time,
int(ir * 1000.0 / time));
1321 if (cfgBenchmark17_Enable)
1327 volumes.
resize(cfgLeaves);
1328 results.
resize(cfgLeaves);
1329 indices.
resize(cfgLeaves);
1330 for (
int i = 0; i < cfgLeaves; ++i)
1333 volumes[i] = btDbvtBenchmark::RandVolume(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale);
1335 for (
int i = 0; i < cfgLeaves; ++i)
1337 btSwap(indices[i], indices[rand() % cfgLeaves]);
1339 printf(
"[17] btDbvtVolume select: ");
1341 for (
int i = 0; i < cfgBenchmark17_Iterations; ++i)
1343 for (
int j = 0; j < cfgLeaves; ++j)
1345 for (
int k = 0; k < cfgLeaves; ++k)
1347 const int idx = indices[k];
1348 results[idx] =
Select(volumes[idx], volumes[j], volumes[k]);
1353 printf(
"%u ms (%i%%)\r\n", time, (time - cfgBenchmark17_Reference) * 100 / time);