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;