38 #define BOOST_TEST_MODULE COAL_BROADPHASE 
   39 #include <boost/test/included/unit_test.hpp> 
   41 #include "coal/config.hh" 
   48 #include <sparsehash/sparse_hash_map> 
   49 #include <sparsehash/dense_hash_map> 
   53 #include <boost/math/constants/constants.hpp> 
   63                                       double env_scale, std::size_t n);
 
   68                                           double env_scale, std::size_t n);
 
   72                                std::size_t query_size, 
bool use_mesh = 
false);
 
   76                                     bool use_mesh = 
false);
 
   81 template <
typename U, 
typename V>
 
   82 struct GoogleSparseHashTable
 
   83     : 
public google::sparse_hash_map<U, V, std::tr1::hash<size_t>,
 
   84                                      std::equal_to<size_t> > {};
 
   86 template <
typename U, 
typename V>
 
   87 struct GoogleDenseHashTable
 
   88     : 
public google::dense_hash_map<U, V, std::tr1::hash<size_t>,
 
   89                                     std::equal_to<size_t> > {
 
   90   GoogleDenseHashTable()
 
   91       : google::dense_hash_map<
U, 
V, std::tr1::hash<size_t>,
 
   92                                std::equal_to<size_t> >() {
 
   93     this->set_empty_key(NULL);
 
  146                                       double env_scale, std::size_t n) {
 
  147   int n_edge = 
static_cast<int>(std::floor(std::pow(n, 1 / 3.0)));
 
  149   CoalScalar step_size = env_scale * 2 / n_edge;
 
  151   CoalScalar single_size = step_size - 2 * delta_size;
 
  154   for (; i < n_edge * n_edge * n_edge / 4; ++i) {
 
  155     int x = i % (n_edge * n_edge);
 
  156     int y = (i - n_edge * n_edge * 
x) % n_edge;
 
  157     int z = i - n_edge * n_edge * 
x - n_edge * 
y;
 
  159     Box* 
box = 
new Box(single_size, single_size, single_size);
 
  161         shared_ptr<CollisionGeometry>(
box),
 
  163             x * step_size + delta_size + 0.5 * single_size - env_scale,
 
  164             y * step_size + delta_size + 0.5 * single_size - env_scale,
 
  165             z * step_size + delta_size + 0.5 * single_size - env_scale))));
 
  166     env.back()->collisionGeometry()->computeLocalAABB();
 
  169   for (; i < n_edge * n_edge * n_edge / 4; ++i) {
 
  170     int x = i % (n_edge * n_edge);
 
  171     int y = (i - n_edge * n_edge * 
x) % n_edge;
 
  172     int z = i - n_edge * n_edge * 
x - n_edge * 
y;
 
  176         shared_ptr<CollisionGeometry>(
sphere),
 
  178             x * step_size + delta_size + 0.5 * single_size - env_scale,
 
  179             y * step_size + delta_size + 0.5 * single_size - env_scale,
 
  180             z * step_size + delta_size + 0.5 * single_size - env_scale))));
 
  181     env.back()->collisionGeometry()->computeLocalAABB();
 
  184   for (; i < n_edge * n_edge * n_edge / 4; ++i) {
 
  185     int x = i % (n_edge * n_edge);
 
  186     int y = (i - n_edge * n_edge * 
x) % n_edge;
 
  187     int z = i - n_edge * n_edge * 
x - n_edge * 
y;
 
  191         shared_ptr<CollisionGeometry>(cylinder),
 
  193             x * step_size + delta_size + 0.5 * single_size - env_scale,
 
  194             y * step_size + delta_size + 0.5 * single_size - env_scale,
 
  195             z * step_size + delta_size + 0.5 * single_size - env_scale))));
 
  196     env.back()->collisionGeometry()->computeLocalAABB();
 
  199   for (; i < n_edge * n_edge * n_edge / 4; ++i) {
 
  200     int x = i % (n_edge * n_edge);
 
  201     int y = (i - n_edge * n_edge * 
x) % n_edge;
 
  202     int z = i - n_edge * n_edge * 
x - n_edge * 
y;
 
  204     Cone* cone = 
new Cone(single_size / 2, single_size);
 
  206         shared_ptr<CollisionGeometry>(cone),
 
  208             x * step_size + delta_size + 0.5 * single_size - env_scale,
 
  209             y * step_size + delta_size + 0.5 * single_size - env_scale,
 
  210             z * step_size + delta_size + 0.5 * single_size - env_scale))));
 
  211     env.back()->collisionGeometry()->computeLocalAABB();
 
  216                                           double env_scale, std::size_t n) {
 
  217   int n_edge = 
static_cast<int>(std::floor(std::pow(n, 1 / 3.0)));
 
  219   CoalScalar step_size = env_scale * 2 / n_edge;
 
  221   CoalScalar single_size = step_size - 2 * delta_size;
 
  224   for (; i < n_edge * n_edge * n_edge / 4; ++i) {
 
  225     int x = i % (n_edge * n_edge);
 
  226     int y = (i - n_edge * n_edge * 
x) % n_edge;
 
  227     int z = i - n_edge * n_edge * 
x - n_edge * 
y;
 
  229     Box box(single_size, single_size, single_size);
 
  233         shared_ptr<CollisionGeometry>(model),
 
  235             x * step_size + delta_size + 0.5 * single_size - env_scale,
 
  236             y * step_size + delta_size + 0.5 * single_size - env_scale,
 
  237             z * step_size + delta_size + 0.5 * single_size - env_scale))));
 
  238     env.back()->collisionGeometry()->computeLocalAABB();
 
  241   for (; i < n_edge * n_edge * n_edge / 4; ++i) {
 
  242     int x = i % (n_edge * n_edge);
 
  243     int y = (i - n_edge * n_edge * 
x) % n_edge;
 
  244     int z = i - n_edge * n_edge * 
x - n_edge * 
y;
 
  250         shared_ptr<CollisionGeometry>(model),
 
  252             x * step_size + delta_size + 0.5 * single_size - env_scale,
 
  253             y * step_size + delta_size + 0.5 * single_size - env_scale,
 
  254             z * step_size + delta_size + 0.5 * single_size - env_scale))));
 
  255     env.back()->collisionGeometry()->computeLocalAABB();
 
  258   for (; i < n_edge * n_edge * n_edge / 4; ++i) {
 
  259     int x = i % (n_edge * n_edge);
 
  260     int y = (i - n_edge * n_edge * 
x) % n_edge;
 
  261     int z = i - n_edge * n_edge * 
x - n_edge * 
y;
 
  263     Cylinder cylinder(single_size / 2, single_size);
 
  267         shared_ptr<CollisionGeometry>(model),
 
  269             x * step_size + delta_size + 0.5 * single_size - env_scale,
 
  270             y * step_size + delta_size + 0.5 * single_size - env_scale,
 
  271             z * step_size + delta_size + 0.5 * single_size - env_scale))));
 
  272     env.back()->collisionGeometry()->computeLocalAABB();
 
  275   for (; i < n_edge * n_edge * n_edge / 4; ++i) {
 
  276     int x = i % (n_edge * n_edge);
 
  277     int y = (i - n_edge * n_edge * 
x) % n_edge;
 
  278     int z = i - n_edge * n_edge * 
x - n_edge * 
y;
 
  280     Cone cone(single_size / 2, single_size);
 
  284         shared_ptr<CollisionGeometry>(model),
 
  286             x * step_size + delta_size + 0.5 * single_size - env_scale,
 
  287             y * step_size + delta_size + 0.5 * single_size - env_scale,
 
  288             z * step_size + delta_size + 0.5 * single_size - env_scale))));
 
  289     env.back()->collisionGeometry()->computeLocalAABB();
 
  295   std::vector<TStruct> 
ts;
 
  296   std::vector<BenchTimer> timers;
 
  298   std::vector<CollisionObject*> env;
 
  304   std::vector<BroadPhaseCollisionManager*> managers;
 
  311   Vec3s lower_limit, upper_limit;
 
  314       std::min(std::min((upper_limit[0] - lower_limit[0]) / 5,
 
  315                         (upper_limit[1] - lower_limit[1]) / 5),
 
  316                (upper_limit[2] - lower_limit[2]) / 5);
 
  321       cell_size, lower_limit, upper_limit));
 
  326           cell_size, lower_limit, upper_limit));
 
  330           cell_size, lower_limit, upper_limit));
 
  337     m->tree_init_level = 2;
 
  338     managers.push_back(
m);
 
  344     m->tree_init_level = 2;
 
  345     managers.push_back(
m);
 
  348   ts.resize(managers.size());
 
  349   timers.resize(managers.size());
 
  351   for (
size_t i = 0; i < managers.size(); ++i) {
 
  353     managers[i]->registerObjects(env);
 
  355     ts[i].push_back(timers[i].getElapsedTime());
 
  358   for (
size_t i = 0; i < managers.size(); ++i) {
 
  360     managers[i]->setup();
 
  362     ts[i].push_back(timers[i].getElapsedTime());
 
  365   std::vector<DistanceCallBackDefault> self_callbacks(managers.size());
 
  367   for (
size_t i = 0; i < self_callbacks.size(); ++i) {
 
  369     managers[i]->distance(&self_callbacks[i]);
 
  371     ts[i].push_back(timers[i].getElapsedTime());
 
  376   for (
size_t i = 1; i < managers.size(); ++i)
 
  377     BOOST_CHECK(fabs(self_callbacks[0].
data.result.min_distance -
 
  378                      self_callbacks[i].data.result.min_distance) < 
DELTA ||
 
  379                 fabs(self_callbacks[0].
data.result.min_distance -
 
  380                      self_callbacks[i].data.result.min_distance) /
 
  381                         fabs(self_callbacks[0].
data.result.min_distance) <
 
  384   for (
size_t i = 0; i < env.size(); ++i) 
delete env[i];
 
  386   for (
size_t i = 0; i < managers.size(); ++i) 
delete managers[i];
 
  388   std::cout.setf(std::ios_base::left, std::ios_base::adjustfield);
 
  391   std::cout << 
"self distance timing summary" << std::endl;
 
  392   std::cout << env.size() << 
" objs" << std::endl;
 
  393   std::cout << 
"register time" << std::endl;
 
  394   for (
size_t i = 0; i < 
ts.size(); ++i)
 
  395     std::cout << std::setw(w) << 
ts[i].records[0] << 
" ";
 
  396   std::cout << std::endl;
 
  398   std::cout << 
"setup time" << std::endl;
 
  399   for (
size_t i = 0; i < 
ts.size(); ++i)
 
  400     std::cout << std::setw(w) << 
ts[i].records[1] << 
" ";
 
  401   std::cout << std::endl;
 
  403   std::cout << 
"self distance time" << std::endl;
 
  404   for (
size_t i = 0; i < 
ts.size(); ++i)
 
  405     std::cout << std::setw(w) << 
ts[i].records[2] << 
" ";
 
  406   std::cout << std::endl;
 
  408   std::cout << 
"overall time" << std::endl;
 
  409   for (
size_t i = 0; i < 
ts.size(); ++i)
 
  410     std::cout << std::setw(w) << 
ts[i].overall_time << 
" ";
 
  411   std::cout << std::endl;
 
  412   std::cout << std::endl;
 
  416                                std::size_t query_size, 
bool use_mesh) {
 
  417   std::vector<TStruct> 
ts;
 
  418   std::vector<BenchTimer> timers;
 
  420   std::vector<CollisionObject*> env;
 
  426   std::vector<CollisionObject*> query;
 
  429   for (std::size_t i = 0; i < env.size(); ++i) manager->
registerObject(env[i]);
 
  433     std::vector<CollisionObject*> candidates;
 
  439     for (std::size_t i = 0; i < candidates.size(); ++i) {
 
  442       if (
callback.data.result.numContacts() == 0)
 
  443         query.push_back(candidates[i]);
 
  445         delete candidates[i];
 
  446       if (query.size() == query_size) 
break;
 
  449     if (query.size() == query_size) 
break;
 
  454   std::vector<BroadPhaseCollisionManager*> managers;
 
  461   Vec3s lower_limit, upper_limit;
 
  464       std::min(std::min((upper_limit[0] - lower_limit[0]) / 20,
 
  465                         (upper_limit[1] - lower_limit[1]) / 20),
 
  466                (upper_limit[2] - lower_limit[2]) / 20);
 
  471       cell_size, lower_limit, upper_limit));
 
  476           cell_size, lower_limit, upper_limit));
 
  480           cell_size, lower_limit, upper_limit));
 
  487     m->tree_init_level = 2;
 
  488     managers.push_back(
m);
 
  494     m->tree_init_level = 2;
 
  495     managers.push_back(
m);
 
  498   ts.resize(managers.size());
 
  499   timers.resize(managers.size());
 
  501   for (
size_t i = 0; i < managers.size(); ++i) {
 
  503     managers[i]->registerObjects(env);
 
  505     ts[i].push_back(timers[i].getElapsedTime());
 
  508   for (
size_t i = 0; i < managers.size(); ++i) {
 
  510     managers[i]->setup();
 
  512     ts[i].push_back(timers[i].getElapsedTime());
 
  515   for (
size_t i = 0; i < query.size(); ++i) {
 
  516     std::vector<DistanceCallBackDefault> query_callbacks(managers.size());
 
  517     for (
size_t j = 0; j < managers.size(); ++j) {
 
  519       managers[j]->distance(query[i], &query_callbacks[j]);
 
  521       ts[j].push_back(timers[j].getElapsedTime());
 
  522       std::cout << query_callbacks[j].data.result.min_distance << 
" ";
 
  524     std::cout << std::endl;
 
  526     for (
size_t j = 1; j < managers.size(); ++j) {
 
  527       bool test = fabs(query_callbacks[0].
data.result.min_distance -
 
  528                        query_callbacks[j].data.result.min_distance) < 
DELTA ||
 
  529                   fabs(query_callbacks[0].
data.result.min_distance -
 
  530                        query_callbacks[j].data.result.min_distance) /
 
  531                           fabs(query_callbacks[0].
data.result.min_distance) <
 
  537         std::cout << 
"j: " << 
typeid(
self).
name() << std::endl;
 
  538         std::cout << 
"query_callbacks[0].data.result.min_distance: " 
  539                   << query_callbacks[0].data.result.min_distance << std::endl;
 
  540         std::cout << 
"query_callbacks[j].data.result.min_distance: " 
  541                   << query_callbacks[j].data.result.min_distance << std::endl;
 
  546   for (std::size_t i = 0; i < env.size(); ++i) 
delete env[i];
 
  547   for (std::size_t i = 0; i < query.size(); ++i) 
delete query[i];
 
  549   for (
size_t i = 0; i < managers.size(); ++i) 
delete managers[i];
 
  551   std::cout.setf(std::ios_base::left, std::ios_base::adjustfield);
 
  554   std::cout << 
"distance timing summary" << std::endl;
 
  555   std::cout << env_size << 
" objs, " << query_size << 
" queries" << std::endl;
 
  556   std::cout << 
"register time" << std::endl;
 
  557   for (
size_t i = 0; i < 
ts.size(); ++i)
 
  558     std::cout << std::setw(w) << 
ts[i].records[0] << 
" ";
 
  559   std::cout << std::endl;
 
  561   std::cout << 
"setup time" << std::endl;
 
  562   for (
size_t i = 0; i < 
ts.size(); ++i)
 
  563     std::cout << std::setw(w) << 
ts[i].records[1] << 
" ";
 
  564   std::cout << std::endl;
 
  566   std::cout << 
"distance time" << std::endl;
 
  567   for (
size_t i = 0; i < 
ts.size(); ++i) {
 
  569     for (
size_t j = 2; j < 
ts[i].records.size(); ++j) tmp += 
ts[i].records[j];
 
  570     std::cout << std::setw(w) << tmp << 
" ";
 
  572   std::cout << std::endl;
 
  574   std::cout << 
"overall time" << std::endl;
 
  575   for (
size_t i = 0; i < 
ts.size(); ++i)
 
  576     std::cout << std::setw(w) << 
ts[i].overall_time << 
" ";
 
  577   std::cout << std::endl;
 
  578   std::cout << std::endl;