BVH_utility.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2011-2014, Willow Garage, Inc.
5  * Copyright (c) 2014-2015, Open Source Robotics Foundation
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of Open Source Robotics Foundation nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
38 #include "coal/BVH/BVH_utility.h"
42 
43 namespace coal {
44 
45 namespace details {
46 template <typename BV>
47 BVHModel<BV>* BVHExtract(const BVHModel<BV>& model, const Transform3s& pose,
48  const AABB& _aabb) {
49  assert(model.getModelType() == BVH_MODEL_TRIANGLES);
50  const Matrix3s& q = pose.getRotation();
51  AABB aabb = translate(_aabb, -pose.getTranslation());
52 
53  Transform3s box_pose;
54  Box box;
55  constructBox(_aabb, box, box_pose);
56  box_pose = pose.inverseTimes(box_pose);
57 
58  GJKSolver gjk;
59  // Early-stop GJK as soon as a separating plane is found
60  gjk.gjk.setDistanceEarlyBreak(1e-3);
61 
62  // Check what triangles should be kept.
63  // TODO use the BV hierarchy
64  std::vector<bool> keep_vertex(model.num_vertices, false);
65  std::vector<bool> keep_tri(model.num_tris, false);
66  unsigned int ntri = 0;
67  const std::vector<Vec3s>& model_vertices_ = *(model.vertices);
68  const std::vector<Triangle>& model_tri_indices_ = *(model.tri_indices);
69  for (unsigned int i = 0; i < model.num_tris; ++i) {
70  const Triangle& t = model_tri_indices_[i];
71 
72  bool keep_this_tri =
73  keep_vertex[t[0]] || keep_vertex[t[1]] || keep_vertex[t[2]];
74 
75  if (!keep_this_tri) {
76  for (unsigned int j = 0; j < 3; ++j) {
77  if (aabb.contain(q * model_vertices_[t[j]])) {
78  keep_this_tri = true;
79  break;
80  }
81  }
82 
83  const TriangleP tri(model_vertices_[t[0]], model_vertices_[t[1]],
84  model_vertices_[t[2]]);
85  const bool enable_nearest_points = false;
86  const bool compute_penetration = false; // we only need to know if there
87  // is a collision or not
88  const DistanceRequest distanceRequest(enable_nearest_points,
89  compute_penetration);
90  DistanceResult distanceResult;
91  const CoalScalar distance = ShapeShapeDistance<Box, TriangleP>(
92  &box, box_pose, &tri, Transform3s(), &gjk, distanceRequest,
93  distanceResult);
94  bool is_collision =
95  (distance <= gjk.getDistancePrecision(compute_penetration));
96 
97  if (!keep_this_tri && is_collision) {
98  keep_this_tri = true;
99  }
100  }
101  if (keep_this_tri) {
102  keep_vertex[t[0]] = keep_vertex[t[1]] = keep_vertex[t[2]] = true;
103  keep_tri[i] = true;
104  ntri++;
105  }
106  }
107 
108  if (ntri == 0) return NULL;
109 
110  BVHModel<BV>* new_model(new BVHModel<BV>());
111  new_model->beginModel(ntri, std::min(ntri * 3, model.num_vertices));
112  std::vector<unsigned int> idxConversion(model.num_vertices);
113  assert(new_model->num_vertices == 0);
114  std::vector<Vec3s>& new_model_vertices_ = *(new_model->vertices);
115  for (unsigned int i = 0; i < keep_vertex.size(); ++i) {
116  if (keep_vertex[i]) {
117  idxConversion[i] = new_model->num_vertices;
118  new_model_vertices_[new_model->num_vertices] = model_vertices_[i];
119  new_model->num_vertices++;
120  }
121  }
122  assert(new_model->num_tris == 0);
123  std::vector<Triangle>& new_model_tri_indices_ = *(new_model->tri_indices);
124  for (unsigned int i = 0; i < keep_tri.size(); ++i) {
125  if (keep_tri[i]) {
126  new_model_tri_indices_[new_model->num_tris].set(
127  idxConversion[model_tri_indices_[i][0]],
128  idxConversion[model_tri_indices_[i][1]],
129  idxConversion[model_tri_indices_[i][2]]);
130  new_model->num_tris++;
131  }
132  }
133  if (new_model->endModel() != BVH_OK) {
134  delete new_model;
135  return NULL;
136  }
137  return new_model;
138 }
139 } // namespace details
140 
141 template <>
143  const AABB& aabb) {
144  return details::BVHExtract(model, pose, aabb);
145 }
146 template <>
148  const AABB& aabb) {
149  return details::BVHExtract(model, pose, aabb);
150 }
151 template <>
153  const AABB& aabb) {
154  return details::BVHExtract(model, pose, aabb);
155 }
156 template <>
158  const AABB& aabb) {
159  return details::BVHExtract(model, pose, aabb);
160 }
161 template <>
163  const Transform3s& pose, const AABB& aabb) {
164  return details::BVHExtract(model, pose, aabb);
165 }
166 template <>
168  const Transform3s& pose, const AABB& aabb) {
169  return details::BVHExtract(model, pose, aabb);
170 }
171 template <>
173  const Transform3s& pose, const AABB& aabb) {
174  return details::BVHExtract(model, pose, aabb);
175 }
176 template <>
178  const Transform3s& pose, const AABB& aabb) {
179  return details::BVHExtract(model, pose, aabb);
180 }
181 
182 void getCovariance(Vec3s* ps, Vec3s* ps2, Triangle* ts, unsigned int* indices,
183  unsigned int n, Matrix3s& M) {
184  Vec3s S1(Vec3s::Zero());
185  Vec3s S2[3] = {Vec3s::Zero(), Vec3s::Zero(), Vec3s::Zero()};
186 
187  if (ts) {
188  for (unsigned int i = 0; i < n; ++i) {
189  const Triangle& t = (indices) ? ts[indices[i]] : ts[i];
190 
191  const Vec3s& p1 = ps[t[0]];
192  const Vec3s& p2 = ps[t[1]];
193  const Vec3s& p3 = ps[t[2]];
194 
195  S1[0] += (p1[0] + p2[0] + p3[0]);
196  S1[1] += (p1[1] + p2[1] + p3[1]);
197  S1[2] += (p1[2] + p2[2] + p3[2]);
198  S2[0][0] += (p1[0] * p1[0] + p2[0] * p2[0] + p3[0] * p3[0]);
199  S2[1][1] += (p1[1] * p1[1] + p2[1] * p2[1] + p3[1] * p3[1]);
200  S2[2][2] += (p1[2] * p1[2] + p2[2] * p2[2] + p3[2] * p3[2]);
201  S2[0][1] += (p1[0] * p1[1] + p2[0] * p2[1] + p3[0] * p3[1]);
202  S2[0][2] += (p1[0] * p1[2] + p2[0] * p2[2] + p3[0] * p3[2]);
203  S2[1][2] += (p1[1] * p1[2] + p2[1] * p2[2] + p3[1] * p3[2]);
204 
205  if (ps2) {
206  const Vec3s& p1 = ps2[t[0]];
207  const Vec3s& p2 = ps2[t[1]];
208  const Vec3s& p3 = ps2[t[2]];
209 
210  S1[0] += (p1[0] + p2[0] + p3[0]);
211  S1[1] += (p1[1] + p2[1] + p3[1]);
212  S1[2] += (p1[2] + p2[2] + p3[2]);
213 
214  S2[0][0] += (p1[0] * p1[0] + p2[0] * p2[0] + p3[0] * p3[0]);
215  S2[1][1] += (p1[1] * p1[1] + p2[1] * p2[1] + p3[1] * p3[1]);
216  S2[2][2] += (p1[2] * p1[2] + p2[2] * p2[2] + p3[2] * p3[2]);
217  S2[0][1] += (p1[0] * p1[1] + p2[0] * p2[1] + p3[0] * p3[1]);
218  S2[0][2] += (p1[0] * p1[2] + p2[0] * p2[2] + p3[0] * p3[2]);
219  S2[1][2] += (p1[1] * p1[2] + p2[1] * p2[2] + p3[1] * p3[2]);
220  }
221  }
222  } else {
223  for (unsigned int i = 0; i < n; ++i) {
224  const Vec3s& p = (indices) ? ps[indices[i]] : ps[i];
225  S1 += p;
226  S2[0][0] += (p[0] * p[0]);
227  S2[1][1] += (p[1] * p[1]);
228  S2[2][2] += (p[2] * p[2]);
229  S2[0][1] += (p[0] * p[1]);
230  S2[0][2] += (p[0] * p[2]);
231  S2[1][2] += (p[1] * p[2]);
232 
233  if (ps2) // another frame
234  {
235  const Vec3s& p = (indices) ? ps2[indices[i]] : ps2[i];
236  S1 += p;
237  S2[0][0] += (p[0] * p[0]);
238  S2[1][1] += (p[1] * p[1]);
239  S2[2][2] += (p[2] * p[2]);
240  S2[0][1] += (p[0] * p[1]);
241  S2[0][2] += (p[0] * p[2]);
242  S2[1][2] += (p[1] * p[2]);
243  }
244  }
245  }
246 
247  unsigned int n_points = ((ps2) ? 2 : 1) * ((ts) ? 3 : 1) * n;
248 
249  M(0, 0) = S2[0][0] - S1[0] * S1[0] / n_points;
250  M(1, 1) = S2[1][1] - S1[1] * S1[1] / n_points;
251  M(2, 2) = S2[2][2] - S1[2] * S1[2] / n_points;
252  M(0, 1) = S2[0][1] - S1[0] * S1[1] / n_points;
253  M(1, 2) = S2[1][2] - S1[1] * S1[2] / n_points;
254  M(0, 2) = S2[0][2] - S1[0] * S1[2] / n_points;
255  M(1, 0) = M(0, 1);
256  M(2, 0) = M(0, 2);
257  M(2, 1) = M(1, 2);
258 }
259 
264  unsigned int* indices, unsigned int n,
265  const Matrix3s& axes, Vec3s& origin,
266  CoalScalar l[2], CoalScalar& r) {
267  bool indirect_index = true;
268  if (!indices) indirect_index = false;
269 
270  unsigned int size_P = ((ps2) ? 2 : 1) * ((ts) ? 3 : 1) * n;
271 
272  CoalScalar(*P)[3] = new CoalScalar[size_P][3];
273 
274  int P_id = 0;
275 
276  if (ts) {
277  for (unsigned int i = 0; i < n; ++i) {
278  unsigned int index = indirect_index ? indices[i] : i;
279  const Triangle& t = ts[index];
280 
281  for (Triangle::index_type j = 0; j < 3; ++j) {
282  Triangle::index_type point_id = t[j];
283  const Vec3s& p = ps[point_id];
284  Vec3s v(p[0], p[1], p[2]);
285  P[P_id][0] = axes.col(0).dot(v);
286  P[P_id][1] = axes.col(1).dot(v);
287  P[P_id][2] = axes.col(2).dot(v);
288  P_id++;
289  }
290 
291  if (ps2) {
292  for (Triangle::index_type j = 0; j < 3; ++j) {
293  Triangle::index_type point_id = t[j];
294  const Vec3s& p = ps2[point_id];
295  // FIXME Is this right ?????
296  Vec3s v(p[0], p[1], p[2]);
297  P[P_id][0] = axes.col(0).dot(v);
298  P[P_id][1] = axes.col(0).dot(v);
299  P[P_id][2] = axes.col(1).dot(v);
300  P_id++;
301  }
302  }
303  }
304  } else {
305  for (unsigned int i = 0; i < n; ++i) {
306  unsigned int index = indirect_index ? indices[i] : i;
307 
308  const Vec3s& p = ps[index];
309  Vec3s v(p[0], p[1], p[2]);
310  P[P_id][0] = axes.col(0).dot(v);
311  P[P_id][1] = axes.col(1).dot(v);
312  P[P_id][2] = axes.col(2).dot(v);
313  P_id++;
314 
315  if (ps2) {
316  const Vec3s& v = ps2[index];
317  P[P_id][0] = axes.col(0).dot(v);
318  P[P_id][1] = axes.col(1).dot(v);
319  P[P_id][2] = axes.col(2).dot(v);
320  P_id++;
321  }
322  }
323  }
324 
325  CoalScalar minx, maxx, miny, maxy, minz, maxz;
326 
327  CoalScalar cz, radsqr;
328 
329  minz = maxz = P[0][2];
330 
331  for (unsigned int i = 1; i < size_P; ++i) {
332  CoalScalar z_value = P[i][2];
333  if (z_value < minz)
334  minz = z_value;
335  else if (z_value > maxz)
336  maxz = z_value;
337  }
338 
339  r = (CoalScalar)0.5 * (maxz - minz);
340  radsqr = r * r;
341  cz = (CoalScalar)0.5 * (maxz + minz);
342 
343  // compute an initial norm of rectangle along x direction
344 
345  // find minx and maxx as starting points
346 
347  unsigned int minindex = 0, maxindex = 0;
348  CoalScalar mintmp, maxtmp;
349  mintmp = maxtmp = P[0][0];
350 
351  for (unsigned int i = 1; i < size_P; ++i) {
352  CoalScalar x_value = P[i][0];
353  if (x_value < mintmp) {
354  minindex = i;
355  mintmp = x_value;
356  } else if (x_value > maxtmp) {
357  maxindex = i;
358  maxtmp = x_value;
359  }
360  }
361 
362  CoalScalar x, dz;
363  dz = P[minindex][2] - cz;
364  minx = P[minindex][0] + std::sqrt(std::max<CoalScalar>(radsqr - dz * dz, 0));
365  dz = P[maxindex][2] - cz;
366  maxx = P[maxindex][0] - std::sqrt(std::max<CoalScalar>(radsqr - dz * dz, 0));
367 
368  // grow minx/maxx
369 
370  for (unsigned int i = 0; i < size_P; ++i) {
371  if (P[i][0] < minx) {
372  dz = P[i][2] - cz;
373  x = P[i][0] + std::sqrt(std::max<CoalScalar>(radsqr - dz * dz, 0));
374  if (x < minx) minx = x;
375  } else if (P[i][0] > maxx) {
376  dz = P[i][2] - cz;
377  x = P[i][0] - std::sqrt(std::max<CoalScalar>(radsqr - dz * dz, 0));
378  if (x > maxx) maxx = x;
379  }
380  }
381 
382  // compute an initial norm of rectangle along y direction
383 
384  // find miny and maxy as starting points
385 
386  minindex = maxindex = 0;
387  mintmp = maxtmp = P[0][1];
388  for (unsigned int i = 1; i < size_P; ++i) {
389  CoalScalar y_value = P[i][1];
390  if (y_value < mintmp) {
391  minindex = i;
392  mintmp = y_value;
393  } else if (y_value > maxtmp) {
394  maxindex = i;
395  maxtmp = y_value;
396  }
397  }
398 
399  CoalScalar y;
400  dz = P[minindex][2] - cz;
401  miny = P[minindex][1] + std::sqrt(std::max<CoalScalar>(radsqr - dz * dz, 0));
402  dz = P[maxindex][2] - cz;
403  maxy = P[maxindex][1] - std::sqrt(std::max<CoalScalar>(radsqr - dz * dz, 0));
404 
405  // grow miny/maxy
406 
407  for (unsigned int i = 0; i < size_P; ++i) {
408  if (P[i][1] < miny) {
409  dz = P[i][2] - cz;
410  y = P[i][1] + std::sqrt(std::max<CoalScalar>(radsqr - dz * dz, 0));
411  if (y < miny) miny = y;
412  } else if (P[i][1] > maxy) {
413  dz = P[i][2] - cz;
414  y = P[i][1] - std::sqrt(std::max<CoalScalar>(radsqr - dz * dz, 0));
415  if (y > maxy) maxy = y;
416  }
417  }
418 
419  // corners may have some points which are not covered - grow lengths if
420  // necessary quite conservative (can be improved)
421  CoalScalar dx, dy, u, t;
422  CoalScalar a = std::sqrt((CoalScalar)0.5);
423  for (unsigned int i = 0; i < size_P; ++i) {
424  if (P[i][0] > maxx) {
425  if (P[i][1] > maxy) {
426  dx = P[i][0] - maxx;
427  dy = P[i][1] - maxy;
428  u = dx * a + dy * a;
429  t = (a * u - dx) * (a * u - dx) + (a * u - dy) * (a * u - dy) +
430  (cz - P[i][2]) * (cz - P[i][2]);
431  u = u - std::sqrt(std::max<CoalScalar>(radsqr - t, 0));
432  if (u > 0) {
433  maxx += u * a;
434  maxy += u * a;
435  }
436  } else if (P[i][1] < miny) {
437  dx = P[i][0] - maxx;
438  dy = P[i][1] - miny;
439  u = dx * a - dy * a;
440  t = (a * u - dx) * (a * u - dx) + (-a * u - dy) * (-a * u - dy) +
441  (cz - P[i][2]) * (cz - P[i][2]);
442  u = u - std::sqrt(std::max<CoalScalar>(radsqr - t, 0));
443  if (u > 0) {
444  maxx += u * a;
445  miny -= u * a;
446  }
447  }
448  } else if (P[i][0] < minx) {
449  if (P[i][1] > maxy) {
450  dx = P[i][0] - minx;
451  dy = P[i][1] - maxy;
452  u = dy * a - dx * a;
453  t = (-a * u - dx) * (-a * u - dx) + (a * u - dy) * (a * u - dy) +
454  (cz - P[i][2]) * (cz - P[i][2]);
455  u = u - std::sqrt(std::max<CoalScalar>(radsqr - t, 0));
456  if (u > 0) {
457  minx -= u * a;
458  maxy += u * a;
459  }
460  } else if (P[i][1] < miny) {
461  dx = P[i][0] - minx;
462  dy = P[i][1] - miny;
463  u = -dx * a - dy * a;
464  t = (-a * u - dx) * (-a * u - dx) + (-a * u - dy) * (-a * u - dy) +
465  (cz - P[i][2]) * (cz - P[i][2]);
466  u = u - std::sqrt(std::max<CoalScalar>(radsqr - t, 0));
467  if (u > 0) {
468  minx -= u * a;
469  miny -= u * a;
470  }
471  }
472  }
473  }
474 
475  origin.noalias() = axes * Vec3s(minx, miny, cz);
476 
477  l[0] = std::max<CoalScalar>(maxx - minx, 0);
478  l[1] = std::max<CoalScalar>(maxy - miny, 0);
479 
480  delete[] P;
481 }
482 
486 static inline void getExtentAndCenter_pointcloud(Vec3s* ps, Vec3s* ps2,
487  unsigned int* indices,
488  unsigned int n, Matrix3s& axes,
489  Vec3s& center, Vec3s& extent) {
490  bool indirect_index = true;
491  if (!indices) indirect_index = false;
492 
493  CoalScalar real_max = (std::numeric_limits<CoalScalar>::max)();
494 
495  Vec3s min_coord(real_max, real_max, real_max);
496  Vec3s max_coord(-real_max, -real_max, -real_max);
497 
498  for (unsigned int i = 0; i < n; ++i) {
499  unsigned int index = indirect_index ? indices[i] : i;
500 
501  const Vec3s& p = ps[index];
502  Vec3s proj(axes.transpose() * p);
503 
504  for (int j = 0; j < 3; ++j) {
505  if (proj[j] > max_coord[j]) max_coord[j] = proj[j];
506  if (proj[j] < min_coord[j]) min_coord[j] = proj[j];
507  }
508 
509  if (ps2) {
510  const Vec3s& v = ps2[index];
511  proj.noalias() = axes.transpose() * v;
512 
513  for (int j = 0; j < 3; ++j) {
514  if (proj[j] > max_coord[j]) max_coord[j] = proj[j];
515  if (proj[j] < min_coord[j]) min_coord[j] = proj[j];
516  }
517  }
518  }
519 
520  center.noalias() = axes * (max_coord + min_coord) / 2;
521 
522  extent.noalias() = (max_coord - min_coord) / 2;
523 }
524 
528 static inline void getExtentAndCenter_mesh(Vec3s* ps, Vec3s* ps2, Triangle* ts,
529  unsigned int* indices,
530  unsigned int n, Matrix3s& axes,
531  Vec3s& center, Vec3s& extent) {
532  bool indirect_index = true;
533  if (!indices) indirect_index = false;
534 
535  CoalScalar real_max = (std::numeric_limits<CoalScalar>::max)();
536 
537  Vec3s min_coord(real_max, real_max, real_max);
538  Vec3s max_coord(-real_max, -real_max, -real_max);
539 
540  for (unsigned int i = 0; i < n; ++i) {
541  unsigned int index = indirect_index ? indices[i] : i;
542  const Triangle& t = ts[index];
543 
544  for (Triangle::index_type j = 0; j < 3; ++j) {
545  Triangle::index_type point_id = t[j];
546  const Vec3s& p = ps[point_id];
547  Vec3s proj(axes.transpose() * p);
548 
549  for (int k = 0; k < 3; ++k) {
550  if (proj[k] > max_coord[k]) max_coord[k] = proj[k];
551  if (proj[k] < min_coord[k]) min_coord[k] = proj[k];
552  }
553  }
554 
555  if (ps2) {
556  for (Triangle::index_type j = 0; j < 3; ++j) {
557  Triangle::index_type point_id = t[j];
558  const Vec3s& p = ps2[point_id];
559  Vec3s proj(axes.transpose() * p);
560 
561  for (int k = 0; k < 3; ++k) {
562  if (proj[k] > max_coord[k]) max_coord[k] = proj[k];
563  if (proj[k] < min_coord[k]) min_coord[k] = proj[k];
564  }
565  }
566  }
567  }
568 
569  Vec3s o((max_coord + min_coord) / 2);
570 
571  center.noalias() = axes * o;
572 
573  extent.noalias() = (max_coord - min_coord) / 2;
574 }
575 
577  unsigned int* indices, unsigned int n, Matrix3s& axes,
578  Vec3s& center, Vec3s& extent) {
579  if (ts)
580  getExtentAndCenter_mesh(ps, ps2, ts, indices, n, axes, center, extent);
581  else
582  getExtentAndCenter_pointcloud(ps, ps2, indices, n, axes, center, extent);
583 }
584 
585 void circumCircleComputation(const Vec3s& a, const Vec3s& b, const Vec3s& c,
586  Vec3s& center, CoalScalar& radius) {
587  Vec3s e1 = a - c;
588  Vec3s e2 = b - c;
589  CoalScalar e1_len2 = e1.squaredNorm();
590  CoalScalar e2_len2 = e2.squaredNorm();
591  Vec3s e3 = e1.cross(e2);
592  CoalScalar e3_len2 = e3.squaredNorm();
593  radius = e1_len2 * e2_len2 * (e1 - e2).squaredNorm() / e3_len2;
594  radius = std::sqrt(radius) * 0.5;
595 
596  center = (e2 * e1_len2 - e1 * e2_len2).cross(e3) * (0.5 * 1 / e3_len2) + c;
597 }
598 
599 static inline CoalScalar maximumDistance_mesh(Vec3s* ps, Vec3s* ps2,
600  Triangle* ts,
601  unsigned int* indices,
602  unsigned int n,
603  const Vec3s& query) {
604  bool indirect_index = true;
605  if (!indices) indirect_index = false;
606 
607  CoalScalar maxD = 0;
608  for (unsigned int i = 0; i < n; ++i) {
609  unsigned int index = indirect_index ? indices[i] : i;
610  const Triangle& t = ts[index];
611 
612  for (Triangle::index_type j = 0; j < 3; ++j) {
613  Triangle::index_type point_id = t[j];
614  const Vec3s& p = ps[point_id];
615 
616  CoalScalar d = (p - query).squaredNorm();
617  if (d > maxD) maxD = d;
618  }
619 
620  if (ps2) {
621  for (Triangle::index_type j = 0; j < 3; ++j) {
622  Triangle::index_type point_id = t[j];
623  const Vec3s& p = ps2[point_id];
624 
625  CoalScalar d = (p - query).squaredNorm();
626  if (d > maxD) maxD = d;
627  }
628  }
629  }
630 
631  return std::sqrt(maxD);
632 }
633 
635  unsigned int* indices,
636  unsigned int n,
637  const Vec3s& query) {
638  bool indirect_index = true;
639  if (!indices) indirect_index = false;
640 
641  CoalScalar maxD = 0;
642  for (unsigned int i = 0; i < n; ++i) {
643  unsigned int index = indirect_index ? indices[i] : i;
644 
645  const Vec3s& p = ps[index];
646  CoalScalar d = (p - query).squaredNorm();
647  if (d > maxD) maxD = d;
648 
649  if (ps2) {
650  const Vec3s& v = ps2[index];
651  CoalScalar d = (v - query).squaredNorm();
652  if (d > maxD) maxD = d;
653  }
654  }
655 
656  return std::sqrt(maxD);
657 }
658 
660  unsigned int* indices, unsigned int n,
661  const Vec3s& query) {
662  if (ts)
663  return maximumDistance_mesh(ps, ps2, ts, indices, n, query);
664  else
665  return maximumDistance_pointcloud(ps, ps2, indices, n, query);
666 }
667 
668 } // namespace coal
coal::BVHModelBase::beginModel
int beginModel(unsigned int num_tris=0, unsigned int num_vertices=0)
Begin a new BVH model.
Definition: BVH_model.cpp:179
coal::Vec3s
Eigen::Matrix< CoalScalar, 3, 1 > Vec3s
Definition: coal/data_types.h:77
coal::details::BVHExtract
BVHModel< BV > * BVHExtract(const BVHModel< BV > &model, const Transform3s &pose, const AABB &_aabb)
Extract the part of the BVHModel that is inside an AABB. A triangle in collision with the AABB is con...
Definition: BVH_utility.cpp:47
collision_manager.box
box
Definition: collision_manager.py:11
coal::BVHModelBase::vertices
std::shared_ptr< std::vector< Vec3s > > vertices
Geometry point data.
Definition: coal/BVH/BVH_model.h:68
coal::maximumDistance_pointcloud
static CoalScalar maximumDistance_pointcloud(Vec3s *ps, Vec3s *ps2, unsigned int *indices, unsigned int n, const Vec3s &query)
Definition: BVH_utility.cpp:634
coal::BVHModelBase::endModel
int endModel()
End BVH model construction, will build the bounding volume hierarchy.
Definition: BVH_model.cpp:507
coal::circumCircleComputation
COAL_DLLAPI void circumCircleComputation(const Vec3s &a, const Vec3s &b, const Vec3s &c, Vec3s &center, CoalScalar &radius)
Compute the center and radius for a triangle's circumcircle.
Definition: BVH_utility.cpp:585
y
y
doxygen_xml_parser.index
index
Definition: doxygen_xml_parser.py:889
coal
Main namespace.
Definition: coal/broadphase/broadphase_bruteforce.h:44
narrowphase.h
coal::Triangle::index_type
std::size_t index_type
Definition: coal/data_types.h:113
octree.r
r
Definition: octree.py:9
coal::GJKSolver
collision and distance solver based on the GJK and EPA algorithms. Originally, GJK and EPA were imple...
Definition: coal/narrowphase/narrowphase.h:57
coal::getExtentAndCenter
COAL_DLLAPI void getExtentAndCenter(Vec3s *ps, Vec3s *ps2, Triangle *ts, unsigned int *indices, unsigned int n, Matrix3s &axes, Vec3s &center, Vec3s &extent)
Compute the bounding volume extent and center for a set or subset of points, given the BV axises.
Definition: BVH_utility.cpp:576
coal::distance
COAL_DLLAPI CoalScalar distance(const Matrix3s &R0, const Vec3s &T0, const kIOS &b1, const kIOS &b2, Vec3s *P=NULL, Vec3s *Q=NULL)
Approximate distance between two kIOS bounding volumes.
Definition: kIOS.cpp:180
coal::maximumDistance
COAL_DLLAPI CoalScalar maximumDistance(Vec3s *ps, Vec3s *ps2, Triangle *ts, unsigned int *indices, unsigned int n, const Vec3s &query)
Compute the maximum distance from a given center point to a point cloud.
Definition: BVH_utility.cpp:659
coal::Transform3s::inverseTimes
Transform3s inverseTimes(const Transform3s &other) const
inverse the transform and multiply with another
Definition: coal/math/transform.h:175
coal::AABB
A class describing the AABB collision structure, which is a box in 3D space determined by two diagona...
Definition: coal/BV/AABB.h:55
a
list a
coal::BVHExtract
COAL_DLLAPI BVHModel< BV > * BVHExtract(const BVHModel< BV > &model, const Transform3s &pose, const AABB &aabb)
Extract the part of the BVHModel that is inside an AABB. A triangle in collision with the AABB is con...
Definition: BVH_utility.cpp:47
coal::Box
Center at zero point, axis aligned box.
Definition: coal/shape/geometric_shapes.h:166
coal::Transform3s
Simple transform class used locally by InterpMotion.
Definition: coal/math/transform.h:55
coal::constructBox
COAL_DLLAPI void constructBox(const AABB &bv, Box &box, Transform3s &tf)
construct a box shape (with a configuration) from a given bounding volume
Definition: geometric_shapes_utility.cpp:1011
shape_shape_func.h
coal::BVH_MODEL_TRIANGLES
@ BVH_MODEL_TRIANGLES
unknown model type
Definition: coal/BVH/BVH_internal.h:81
coal::DistanceRequest
request to the distance computation
Definition: coal/collision_data.h:985
d
d
c
c
P
P
coal::BVHModelBase::getModelType
BVHModelType getModelType() const
Model type described by the instance.
Definition: coal/BVH/BVH_model.h:89
coal::getExtentAndCenter_mesh
static void getExtentAndCenter_mesh(Vec3s *ps, Vec3s *ps2, Triangle *ts, unsigned int *indices, unsigned int n, Matrix3s &axes, Vec3s &center, Vec3s &extent)
Compute the bounding volume extent and center for a set or subset of points. The bounding volume axes...
Definition: BVH_utility.cpp:528
x
x
coal::DistanceResult
distance result
Definition: coal/collision_data.h:1051
coal::BVH_OK
@ BVH_OK
Definition: coal/BVH/BVH_internal.h:64
M
M
coal::translate
static AABB translate(const AABB &aabb, const Vec3s &t)
translate the center of AABB by t
Definition: coal/BV/AABB.h:233
coal::maximumDistance_mesh
static CoalScalar maximumDistance_mesh(Vec3s *ps, Vec3s *ps2, Triangle *ts, unsigned int *indices, unsigned int n, const Vec3s &query)
Definition: BVH_utility.cpp:599
q
q
coal::getRadiusAndOriginAndRectangleSize
COAL_DLLAPI void getRadiusAndOriginAndRectangleSize(Vec3s *ps, Vec3s *ps2, Triangle *ts, unsigned int *indices, unsigned int n, const Matrix3s &axes, Vec3s &origin, CoalScalar l[2], CoalScalar &r)
Compute the RSS bounding volume parameters: radius, rectangle size and the origin,...
Definition: BVH_utility.cpp:263
coal::AABB::contain
bool contain(const Vec3s &p) const
Check whether the AABB contains a point.
Definition: coal/BV/AABB.h:102
coal::Transform3s::getRotation
const Matrix3s & getRotation() const
get rotation
Definition: coal/math/transform.h:110
octree.p1
tuple p1
Definition: octree.py:54
coal::TriangleP
Triangle stores the points instead of only indices of points.
Definition: coal/shape/geometric_shapes.h:110
coal::KDOP
KDOP class describes the KDOP collision structures. K is set as the template parameter,...
Definition: coal/BV/kDOP.h:91
generate_distance_plot.b
float b
Definition: generate_distance_plot.py:7
coal::BVHModelBase::tri_indices
std::shared_ptr< std::vector< Triangle > > tri_indices
Geometry triangle index data, will be NULL for point clouds.
Definition: coal/BVH/BVH_model.h:71
coal::BVHModel
A class describing the bounding hierarchy of a mesh model or a point cloud model (which is viewed as ...
Definition: coal/BVH/BVH_model.h:314
coal::Matrix3s
Eigen::Matrix< CoalScalar, 3, 3 > Matrix3s
Definition: coal/data_types.h:81
geometric_shapes_utility.h
ts
ts
coal::getCovariance
COAL_DLLAPI void getCovariance(Vec3s *ps, Vec3s *ps2, Triangle *ts, unsigned int *indices, unsigned int n, Matrix3s &M)
Compute the covariance matrix for a set or subset of points. if ts = null, then indices refer to poin...
Definition: BVH_utility.cpp:182
coal::getExtentAndCenter_pointcloud
static void getExtentAndCenter_pointcloud(Vec3s *ps, Vec3s *ps2, unsigned int *indices, unsigned int n, Matrix3s &axes, Vec3s &center, Vec3s &extent)
Compute the bounding volume extent and center for a set or subset of points. The bounding volume axes...
Definition: BVH_utility.cpp:486
coal::BVHModelBase::num_vertices
unsigned int num_vertices
Number of points.
Definition: coal/BVH/BVH_model.h:80
BVH_utility.h
coal::Triangle
Triangle with 3 indices for points.
Definition: coal/data_types.h:111
t
dictionary t
coal::BVHModelBase::num_tris
unsigned int num_tris
Number of triangles.
Definition: coal/BVH/BVH_model.h:77
coal::CoalScalar
double CoalScalar
Definition: coal/data_types.h:76
obb.v
list v
Definition: obb.py:48
coal::Transform3s::getTranslation
const Vec3s & getTranslation() const
get translation
Definition: coal/math/transform.h:101
gjk
Definition: doc/gjk.py:1


hpp-fcl
Author(s):
autogenerated on Sat Nov 23 2024 03:44:57