46 template <
typename BV>
62 std::vector<bool> keep_vertex(model.
num_vertices,
false);
63 std::vector<bool> keep_tri(model.
num_tris,
false);
64 unsigned int ntri = 0;
65 for (
unsigned int i = 0; i < model.
num_tris; ++i) {
69 keep_vertex[t[0]] || keep_vertex[t[1]] || keep_vertex[t[2]];
72 for (
unsigned int j = 0; j < 3; ++j) {
85 distance, c1, c2, normal)) {
90 keep_vertex[t[0]] = keep_vertex[t[1]] = keep_vertex[t[2]] =
true;
96 if (ntri == 0)
return NULL;
100 std::vector<unsigned int> idxConversion(model.
num_vertices);
102 for (
unsigned int i = 0; i < keep_vertex.size(); ++i) {
103 if (keep_vertex[i]) {
110 for (
unsigned int i = 0; i < keep_tri.size(); ++i) {
170 Vec3f S1(Vec3f::Zero());
171 Vec3f S2[3] = {Vec3f::Zero(), Vec3f::Zero(), Vec3f::Zero()};
174 for (
unsigned int i = 0; i < n; ++i) {
175 const Triangle&
t = (indices) ? ts[indices[i]] : ts[i];
178 const Vec3f& p2 = ps[t[1]];
179 const Vec3f& p3 = ps[t[2]];
181 S1[0] += (p1[0] + p2[0] + p3[0]);
182 S1[1] += (p1[1] + p2[1] + p3[1]);
183 S1[2] += (p1[2] + p2[2] + p3[2]);
184 S2[0][0] += (p1[0] * p1[0] + p2[0] * p2[0] + p3[0] * p3[0]);
185 S2[1][1] += (p1[1] * p1[1] + p2[1] * p2[1] + p3[1] * p3[1]);
186 S2[2][2] += (p1[2] * p1[2] + p2[2] * p2[2] + p3[2] * p3[2]);
187 S2[0][1] += (p1[0] * p1[1] + p2[0] * p2[1] + p3[0] * p3[1]);
188 S2[0][2] += (p1[0] * p1[2] + p2[0] * p2[2] + p3[0] * p3[2]);
189 S2[1][2] += (p1[1] * p1[2] + p2[1] * p2[2] + p3[1] * p3[2]);
192 const Vec3f& p1 = ps2[t[0]];
193 const Vec3f& p2 = ps2[t[1]];
194 const Vec3f& p3 = ps2[t[2]];
196 S1[0] += (p1[0] + p2[0] + p3[0]);
197 S1[1] += (p1[1] + p2[1] + p3[1]);
198 S1[2] += (p1[2] + p2[2] + p3[2]);
200 S2[0][0] += (p1[0] * p1[0] + p2[0] * p2[0] + p3[0] * p3[0]);
201 S2[1][1] += (p1[1] * p1[1] + p2[1] * p2[1] + p3[1] * p3[1]);
202 S2[2][2] += (p1[2] * p1[2] + p2[2] * p2[2] + p3[2] * p3[2]);
203 S2[0][1] += (p1[0] * p1[1] + p2[0] * p2[1] + p3[0] * p3[1]);
204 S2[0][2] += (p1[0] * p1[2] + p2[0] * p2[2] + p3[0] * p3[2]);
205 S2[1][2] += (p1[1] * p1[2] + p2[1] * p2[2] + p3[1] * p3[2]);
209 for (
unsigned int i = 0; i < n; ++i) {
210 const Vec3f& p = (indices) ? ps[indices[i]] : ps[i];
212 S2[0][0] += (p[0] * p[0]);
213 S2[1][1] += (p[1] * p[1]);
214 S2[2][2] += (p[2] * p[2]);
215 S2[0][1] += (p[0] * p[1]);
216 S2[0][2] += (p[0] * p[2]);
217 S2[1][2] += (p[1] * p[2]);
221 const Vec3f& p = (indices) ? ps2[indices[i]] : ps2[i];
223 S2[0][0] += (p[0] * p[0]);
224 S2[1][1] += (p[1] * p[1]);
225 S2[2][2] += (p[2] * p[2]);
226 S2[0][1] += (p[0] * p[1]);
227 S2[0][2] += (p[0] * p[2]);
228 S2[1][2] += (p[1] * p[2]);
233 unsigned int n_points = ((ps2) ? 2 : 1) * ((ts) ? 3 : 1) * n;
235 M(0, 0) = S2[0][0] - S1[0] * S1[0] / n_points;
236 M(1, 1) = S2[1][1] - S1[1] * S1[1] / n_points;
237 M(2, 2) = S2[2][2] - S1[2] * S1[2] / n_points;
238 M(0, 1) = S2[0][1] - S1[0] * S1[1] / n_points;
239 M(1, 2) = S2[1][2] - S1[1] * S1[2] / n_points;
240 M(0, 2) = S2[0][2] - S1[0] * S1[2] / n_points;
250 unsigned int* indices,
unsigned int n,
253 bool indirect_index =
true;
254 if (!indices) indirect_index =
false;
256 unsigned int size_P = ((ps2) ? 2 : 1) * ((ts) ? 3 : 1) * n;
263 for (
unsigned int i = 0; i < n; ++i) {
264 unsigned int index = indirect_index ? indices[i] : i;
269 const Vec3f& p = ps[point_id];
270 Vec3f v(p[0], p[1], p[2]);
271 P[P_id][0] = axes.col(0).dot(v);
272 P[P_id][1] = axes.col(1).dot(v);
273 P[P_id][2] = axes.col(2).dot(v);
280 const Vec3f& p = ps2[point_id];
282 Vec3f v(p[0], p[1], p[2]);
283 P[P_id][0] = axes.col(0).dot(v);
284 P[P_id][1] = axes.col(0).dot(v);
285 P[P_id][2] = axes.col(1).dot(v);
291 for (
unsigned int i = 0; i < n; ++i) {
292 unsigned int index = indirect_index ? indices[i] : i;
295 Vec3f v(p[0], p[1], p[2]);
296 P[P_id][0] = axes.col(0).dot(v);
297 P[P_id][1] = axes.col(1).dot(v);
298 P[P_id][2] = axes.col(2).dot(v);
303 P[P_id][0] = axes.col(0).dot(v);
304 P[P_id][1] = axes.col(1).dot(v);
305 P[P_id][2] = axes.col(2).dot(v);
311 FCL_REAL minx, maxx, miny, maxy, minz, maxz;
315 minz = maxz =
P[0][2];
317 for (
unsigned int i = 1; i < size_P; ++i) {
321 else if (z_value > maxz)
333 unsigned int minindex = 0, maxindex = 0;
335 mintmp = maxtmp =
P[0][0];
337 for (
unsigned int i = 1; i < size_P; ++i) {
339 if (x_value < mintmp) {
342 }
else if (x_value > maxtmp) {
349 dz =
P[minindex][2] - cz;
350 minx =
P[minindex][0] + std::sqrt(std::max<FCL_REAL>(radsqr - dz * dz, 0));
351 dz =
P[maxindex][2] - cz;
352 maxx =
P[maxindex][0] - std::sqrt(std::max<FCL_REAL>(radsqr - dz * dz, 0));
356 for (
unsigned int i = 0; i < size_P; ++i) {
357 if (
P[i][0] < minx) {
359 x =
P[i][0] + std::sqrt(std::max<FCL_REAL>(radsqr - dz * dz, 0));
360 if (x < minx) minx = x;
361 }
else if (
P[i][0] > maxx) {
363 x =
P[i][0] - std::sqrt(std::max<FCL_REAL>(radsqr - dz * dz, 0));
364 if (x > maxx) maxx = x;
372 minindex = maxindex = 0;
373 mintmp = maxtmp =
P[0][1];
374 for (
unsigned int i = 1; i < size_P; ++i) {
376 if (y_value < mintmp) {
379 }
else if (y_value > maxtmp) {
386 dz =
P[minindex][2] - cz;
387 miny =
P[minindex][1] + std::sqrt(std::max<FCL_REAL>(radsqr - dz * dz, 0));
388 dz =
P[maxindex][2] - cz;
389 maxy =
P[maxindex][1] - std::sqrt(std::max<FCL_REAL>(radsqr - dz * dz, 0));
393 for (
unsigned int i = 0; i < size_P; ++i) {
394 if (
P[i][1] < miny) {
396 y =
P[i][1] + std::sqrt(std::max<FCL_REAL>(radsqr - dz * dz, 0));
397 if (y < miny) miny = y;
398 }
else if (
P[i][1] > maxy) {
400 y =
P[i][1] - std::sqrt(std::max<FCL_REAL>(radsqr - dz * dz, 0));
401 if (y > maxy) maxy = y;
409 for (
unsigned int i = 0; i < size_P; ++i) {
410 if (
P[i][0] > maxx) {
411 if (
P[i][1] > maxy) {
415 t = (a * u - dx) * (a * u - dx) + (a * u - dy) * (a * u - dy) +
416 (cz -
P[i][2]) * (cz -
P[i][2]);
417 u = u - std::sqrt(std::max<FCL_REAL>(radsqr - t, 0));
422 }
else if (
P[i][1] < miny) {
426 t = (a * u - dx) * (a * u - dx) + (-a * u - dy) * (-a * u - dy) +
427 (cz -
P[i][2]) * (cz -
P[i][2]);
428 u = u - std::sqrt(std::max<FCL_REAL>(radsqr - t, 0));
434 }
else if (
P[i][0] < minx) {
435 if (
P[i][1] > maxy) {
439 t = (-a * u - dx) * (-a * u - dx) + (a * u - dy) * (a * u - dy) +
440 (cz -
P[i][2]) * (cz -
P[i][2]);
441 u = u - std::sqrt(std::max<FCL_REAL>(radsqr - t, 0));
446 }
else if (
P[i][1] < miny) {
449 u = -dx * a - dy * a;
450 t = (-a * u - dx) * (-a * u - dx) + (-a * u - dy) * (-a * u - dy) +
451 (cz -
P[i][2]) * (cz -
P[i][2]);
452 u = u - std::sqrt(std::max<FCL_REAL>(radsqr - t, 0));
461 origin.noalias() = axes *
Vec3f(minx, miny, cz);
463 l[0] = std::max<FCL_REAL>(maxx - minx, 0);
464 l[1] = std::max<FCL_REAL>(maxy - miny, 0);
473 unsigned int* indices,
476 bool indirect_index =
true;
477 if (!indices) indirect_index =
false;
479 FCL_REAL real_max = (std::numeric_limits<FCL_REAL>::max)();
481 Vec3f min_coord(real_max, real_max, real_max);
482 Vec3f max_coord(-real_max, -real_max, -real_max);
484 for (
unsigned int i = 0; i < n; ++i) {
485 unsigned int index = indirect_index ? indices[i] : i;
488 Vec3f proj(axes.transpose() * p);
490 for (
int j = 0; j < 3; ++j) {
491 if (proj[j] > max_coord[j]) max_coord[j] = proj[j];
492 if (proj[j] < min_coord[j]) min_coord[j] = proj[j];
497 proj.noalias() = axes.transpose() *
v;
499 for (
int j = 0; j < 3; ++j) {
500 if (proj[j] > max_coord[j]) max_coord[j] = proj[j];
501 if (proj[j] < min_coord[j]) min_coord[j] = proj[j];
506 center.noalias() = axes * (max_coord + min_coord) / 2;
508 extent.noalias() = (max_coord - min_coord) / 2;
515 unsigned int* indices,
518 bool indirect_index =
true;
519 if (!indices) indirect_index =
false;
521 FCL_REAL real_max = (std::numeric_limits<FCL_REAL>::max)();
523 Vec3f min_coord(real_max, real_max, real_max);
524 Vec3f max_coord(-real_max, -real_max, -real_max);
526 for (
unsigned int i = 0; i < n; ++i) {
527 unsigned int index = indirect_index ? indices[i] : i;
532 const Vec3f& p = ps[point_id];
533 Vec3f proj(axes.transpose() * p);
535 for (
int k = 0; k < 3; ++k) {
536 if (proj[k] > max_coord[k]) max_coord[k] = proj[k];
537 if (proj[k] < min_coord[k]) min_coord[k] = proj[k];
544 const Vec3f& p = ps2[point_id];
545 Vec3f proj(axes.transpose() * p);
547 for (
int k = 0; k < 3; ++k) {
548 if (proj[k] > max_coord[k]) max_coord[k] = proj[k];
549 if (proj[k] < min_coord[k]) min_coord[k] = proj[k];
555 Vec3f o((max_coord + min_coord) / 2);
557 center.noalias() = axes * o;
559 extent.noalias() = (max_coord - min_coord) / 2;
563 unsigned int* indices,
unsigned int n,
Matrix3f& axes,
575 FCL_REAL e1_len2 = e1.squaredNorm();
576 FCL_REAL e2_len2 = e2.squaredNorm();
577 Vec3f e3 = e1.cross(e2);
578 FCL_REAL e3_len2 = e3.squaredNorm();
579 radius = e1_len2 * e2_len2 * (e1 - e2).squaredNorm() / e3_len2;
580 radius = std::sqrt(radius) * 0.5;
582 center = (e2 * e1_len2 - e1 * e2_len2).cross(e3) * (0.5 * 1 / e3_len2) + c;
586 unsigned int* indices,
588 const Vec3f& query) {
589 bool indirect_index =
true;
590 if (!indices) indirect_index =
false;
593 for (
unsigned int i = 0; i < n; ++i) {
594 unsigned int index = indirect_index ? indices[i] : i;
599 const Vec3f& p = ps[point_id];
601 FCL_REAL d = (p - query).squaredNorm();
602 if (d > maxD) maxD = d;
608 const Vec3f& p = ps2[point_id];
610 FCL_REAL d = (p - query).squaredNorm();
611 if (d > maxD) maxD = d;
616 return std::sqrt(maxD);
620 unsigned int* indices,
622 const Vec3f& query) {
623 bool indirect_index =
true;
624 if (!indices) indirect_index =
false;
627 for (
unsigned int i = 0; i < n; ++i) {
628 unsigned int index = indirect_index ? indices[i] : i;
631 FCL_REAL d = (p - query).squaredNorm();
632 if (d > maxD) maxD = d;
636 FCL_REAL d = (v - query).squaredNorm();
637 if (d > maxD) maxD = d;
641 return std::sqrt(maxD);
645 unsigned int* indices,
unsigned int n,
646 const Vec3f& query) {
KDOP class describes the KDOP collision structures. K is set as the template parameter, which should be 16, 18, or 24 The KDOP structure is defined by some pairs of parallel planes defined by some axes. For K = 16, the planes are 6 AABB planes and 10 diagonal planes that cut off some space of the edges: (-1,0,0) and (1,0,0) -> indices 0 and 8 (0,-1,0) and (0,1,0) -> indices 1 and 9 (0,0,-1) and (0,0,1) -> indices 2 and 10 (-1,-1,0) and (1,1,0) -> indices 3 and 11 (-1,0,-1) and (1,0,1) -> indices 4 and 12 (0,-1,-1) and (0,1,1) -> indices 5 and 13 (-1,1,0) and (1,-1,0) -> indices 6 and 14 (-1,0,1) and (1,0,-1) -> indices 7 and 15 For K = 18, the planes are 6 AABB planes and 12 diagonal planes that cut off some space of the edges: (-1,0,0) and (1,0,0) -> indices 0 and 9 (0,-1,0) and (0,1,0) -> indices 1 and 10 (0,0,-1) and (0,0,1) -> indices 2 and 11 (-1,-1,0) and (1,1,0) -> indices 3 and 12 (-1,0,-1) and (1,0,1) -> indices 4 and 13 (0,-1,-1) and (0,1,1) -> indices 5 and 14 (-1,1,0) and (1,-1,0) -> indices 6 and 15 (-1,0,1) and (1,0,-1) -> indices 7 and 16 (0,-1,1) and (0,1,-1) -> indices 8 and 17 For K = 18, the planes are 6 AABB planes and 18 diagonal planes that cut off some space of the edges: (-1,0,0) and (1,0,0) -> indices 0 and 12 (0,-1,0) and (0,1,0) -> indices 1 and 13 (0,0,-1) and (0,0,1) -> indices 2 and 14 (-1,-1,0) and (1,1,0) -> indices 3 and 15 (-1,0,-1) and (1,0,1) -> indices 4 and 16 (0,-1,-1) and (0,1,1) -> indices 5 and 17 (-1,1,0) and (1,-1,0) -> indices 6 and 18 (-1,0,1) and (1,0,-1) -> indices 7 and 19 (0,-1,1) and (0,1,-1) -> indices 8 and 20 (-1, -1, 1) and (1, 1, -1) –> indices 9 and 21 (-1, 1, -1) and (1, -1, 1) –> indices 10 and 22 (1, -1, -1) and (-1, 1, 1) –> indices 11 and 23.
static FCL_REAL maximumDistance_pointcloud(Vec3f *ps, Vec3f *ps2, unsigned int *indices, unsigned int n, const Vec3f &query)
Eigen::Matrix< FCL_REAL, 3, 3 > Matrix3f
HPP_FCL_DLLAPI FCL_REAL maximumDistance(Vec3f *ps, Vec3f *ps2, Triangle *ts, unsigned int *indices, unsigned int n, const Vec3f &query)
Compute the maximum distance from a given center point to a point cloud.
static FCL_REAL maximumDistance_mesh(Vec3f *ps, Vec3f *ps2, Triangle *ts, unsigned int *indices, unsigned int n, const Vec3f &query)
HPP_FCL_DLLAPI void circumCircleComputation(const Vec3f &a, const Vec3f &b, const Vec3f &c, Vec3f ¢er, FCL_REAL &radius)
Compute the center and radius for a triangle's circumcircle.
HPP_FCL_DLLAPI void getRadiusAndOriginAndRectangleSize(Vec3f *ps, Vec3f *ps2, Triangle *ts, unsigned int *indices, unsigned int n, const Matrix3f &axes, Vec3f &origin, FCL_REAL l[2], FCL_REAL &r)
Compute the RSS bounding volume parameters: radius, rectangle size and the origin, given the BV axises.
unsigned int num_vertices
Number of points.
static void getExtentAndCenter_pointcloud(Vec3f *ps, Vec3f *ps2, unsigned int *indices, unsigned int n, Matrix3f &axes, Vec3f ¢er, Vec3f &extent)
Compute the bounding volume extent and center for a set or subset of points. The bounding volume axes...
HPP_FCL_DLLAPI FCL_REAL distance(const Matrix3f &R0, const Vec3f &T0, const kIOS &b1, const kIOS &b2, Vec3f *P=NULL, Vec3f *Q=NULL)
Approximate distance between two kIOS bounding volumes.
HPP_FCL_DLLAPI void getCovariance(Vec3f *ps, Vec3f *ps2, Triangle *ts, unsigned int *indices, unsigned int n, Matrix3f &M)
Compute the covariance matrix for a set or subset of points. if ts = null, then indices refer to poin...
HPP_FCL_DLLAPI void getExtentAndCenter(Vec3f *ps, Vec3f *ps2, Triangle *ts, unsigned int *indices, unsigned int n, Matrix3f &axes, Vec3f ¢er, Vec3f &extent)
Compute the bounding volume extent and center for a set or subset of points, given the BV axises...
Triangle * tri_indices
Geometry triangle index data, will be NULL for point clouds.
Vec3f * vertices
Geometry point data.
unsigned int num_tris
Number of triangles.
int beginModel(unsigned int num_tris=0, unsigned int num_vertices=0)
Begin a new BVH model.
Center at zero point, axis aligned box.
BVHModelType getModelType() const
Model type described by the instance.
BVHModel< BV > * BVHExtract(const BVHModel< BV > &model, const Transform3f &pose, const AABB &_aabb)
Extract the part of the BVHModel that is inside an AABB. A triangle in collision with the AABB is con...
A class describing the bounding hierarchy of a mesh model or a point cloud model (which is viewed as ...
A class describing the AABB collision structure, which is a box in 3D space determined by two diagona...
static AABB translate(const AABB &aabb, const Vec3f &t)
translate the center of AABB by t
Triangle with 3 indices for points.
bool shapeTriangleInteraction(const S &s, const Transform3f &tf1, const Vec3f &P1, const Vec3f &P2, const Vec3f &P3, const Transform3f &tf2, FCL_REAL &distance, Vec3f &p1, Vec3f &p2, Vec3f &normal) const
intersection checking between one shape and a triangle with transformation
bool contain(const Vec3f &p) const
Check whether the AABB contains a point.
collision and distance solver based on GJK algorithm implemented in fcl (rewritten the code from the ...
Eigen::Matrix< FCL_REAL, 3, 1 > Vec3f
static void getExtentAndCenter_mesh(Vec3f *ps, Vec3f *ps2, Triangle *ts, unsigned int *indices, unsigned int n, Matrix3f &axes, Vec3f ¢er, Vec3f &extent)
Compute the bounding volume extent and center for a set or subset of points. The bounding volume axes...
HPP_FCL_DLLAPI void constructBox(const AABB &bv, Box &box, Transform3f &tf)
construct a box shape (with a configuration) from a given bounding volume
int endModel()
End BVH model construction, will build the bounding volume hierarchy.