38 #ifndef FCL_GEOMETRY_SHAPE_UTILITY_INL_H
39 #define FCL_GEOMETRY_SHAPE_UTILITY_INL_H
124 template <
typename S,
typename BV,
typename Shape>
129 std::vector<Vector3<S>> convex_bound_vertices = s.getBoundVertices(tf);
130 fit(convex_bound_vertices.data(),
131 static_cast<int>(convex_bound_vertices.size()), bv);
136 template <
typename S>
144 S x_range = 0.5 * (fabs(R(0, 0) * s.
side[0]) + fabs(R(0, 1) * s.
side[1]) + fabs(R(0, 2) * s.
side[2]));
145 S y_range = 0.5 * (fabs(R(1, 0) * s.
side[0]) + fabs(R(1, 1) * s.
side[1]) + fabs(R(1, 2) * s.
side[2]));
146 S z_range = 0.5 * (fabs(R(2, 0) * s.
side[0]) + fabs(R(2, 1) * s.
side[1]) + fabs(R(2, 2) * s.
side[2]));
148 Vector3<S> v_delta(x_range, y_range, z_range);
149 bv.
max_ = T + v_delta;
150 bv.
min_ = T - v_delta;
155 template <
typename S>
160 bv.
axis = tf.linear();
161 bv.
To = tf.translation();
167 template <
typename S>
175 S x_range = 0.5 * fabs(R(0, 2) * s.
lz) + s.
radius;
176 S y_range = 0.5 * fabs(R(1, 2) * s.
lz) + s.
radius;
177 S z_range = 0.5 * fabs(R(2, 2) * s.
lz) + s.
radius;
179 Vector3<S> v_delta(x_range, y_range, z_range);
180 bv.
max_ = T + v_delta;
181 bv.
min_ = T - v_delta;
186 template <
typename S>
191 bv.
axis = tf.linear();
192 bv.
To = tf.translation();
198 template <
typename S>
206 S x_range = fabs(R(0, 0) * s.
radius) + fabs(R(0, 1) * s.
radius) + 0.5 * fabs(R(0, 2) * s.
lz);
207 S y_range = fabs(R(1, 0) * s.
radius) + fabs(R(1, 1) * s.
radius) + 0.5 * fabs(R(1, 2) * s.
lz);
208 S z_range = fabs(R(2, 0) * s.
radius) + fabs(R(2, 1) * s.
radius) + 0.5 * fabs(R(2, 2) * s.
lz);
210 Vector3<S> v_delta(x_range, y_range, z_range);
211 bv.
max_ = T + v_delta;
212 bv.
min_ = T - v_delta;
217 template <
typename S>
222 bv.
axis = tf.linear();
223 bv.
To = tf.translation();
229 template <
typename S>
249 template <
typename S>
256 bv.
axis = tf.linear();
262 template <
typename S>
270 S x_range = fabs(R(0, 0) * s.
radius) + fabs(R(0, 1) * s.
radius) + 0.5 * fabs(R(0, 2) * s.
lz);
271 S y_range = fabs(R(1, 0) * s.
radius) + fabs(R(1, 1) * s.
radius) + 0.5 * fabs(R(1, 2) * s.
lz);
272 S z_range = fabs(R(2, 0) * s.
radius) + fabs(R(2, 1) * s.
radius) + 0.5 * fabs(R(2, 2) * s.
lz);
274 Vector3<S> v_delta(x_range, y_range, z_range);
275 bv.
max_ = T + v_delta;
276 bv.
min_ = T - v_delta;
281 template <
typename S>
286 bv.
axis = tf.linear();
287 bv.
To = tf.translation();
293 template <
typename S>
301 S x_range = (fabs(R(0, 0) * s.
radii[0]) + fabs(R(0, 1) * s.
radii[1]) + fabs(R(0, 2) * s.
radii[2]));
302 S y_range = (fabs(R(1, 0) * s.
radii[0]) + fabs(R(1, 1) * s.
radii[1]) + fabs(R(1, 2) * s.
radii[2]));
303 S z_range = (fabs(R(2, 0) * s.
radii[0]) + fabs(R(2, 1) * s.
radii[1]) + fabs(R(2, 2) * s.
radii[2]));
305 Vector3<S> v_delta(x_range, y_range, z_range);
306 bv.
max_ = T + v_delta;
307 bv.
min_ = T - v_delta;
312 template <
typename S>
317 bv.
axis = tf.linear();
318 bv.
To = tf.translation();
324 template <
typename S>
331 const S& d = new_s.
d;
336 if(n[1] == (S)0.0 && n[2] == (S)0.0)
339 if(n[0] < 0) bv_.
min_[0] = -d;
340 else if(n[0] > 0) bv_.
max_[0] = d;
342 else if(n[0] == (S)0.0 && n[2] == (S)0.0)
345 if(n[1] < 0) bv_.
min_[1] = -d;
346 else if(n[1] > 0) bv_.
max_[1] = d;
348 else if(n[0] == (S)0.0 && n[1] == (S)0.0)
351 if(n[2] < 0) bv_.
min_[2] = -d;
352 else if(n[2] > 0) bv_.
max_[2] = d;
360 template <
typename S>
369 bv.
axis.setIdentity();
376 template <
typename S>
385 bv.
axis.setIdentity();
392 template <
typename S>
403 template <
typename S>
416 template <
typename S>
423 const S& d = new_s.
d;
425 const std::size_t D = 8;
426 for(std::size_t i = 0; i < D; ++i)
428 for(std::size_t i = D; i < 2 * D; ++i)
431 if(n[1] == (S)0.0 && n[2] == (S)0.0)
433 if(n[0] > 0) bv.
dist(D) = d;
434 else bv.
dist(0) = -d;
436 else if(n[0] == (S)0.0 && n[2] == (S)0.0)
438 if(n[1] > 0) bv.
dist(D + 1) = d;
439 else bv.
dist(1) = -d;
441 else if(n[0] == (S)0.0 && n[1] == (S)0.0)
443 if(n[2] > 0) bv.
dist(D + 2) = d;
444 else bv.
dist(2) = -d;
446 else if(n[2] == (S)0.0 && n[0] == n[1])
448 if(n[0] > 0) bv.
dist(D + 3) = n[0] * d * 2;
449 else bv.
dist(3) = n[0] * d * 2;
451 else if(n[1] == (S)0.0 && n[0] == n[2])
453 if(n[1] > 0) bv.
dist(D + 4) = n[0] * d * 2;
454 else bv.
dist(4) = n[0] * d * 2;
456 else if(n[0] == (S)0.0 && n[1] == n[2])
458 if(n[1] > 0) bv.
dist(D + 5) = n[1] * d * 2;
459 else bv.
dist(5) = n[1] * d * 2;
461 else if(n[2] == (S)0.0 && n[0] + n[1] == (S)0.0)
463 if(n[0] > 0) bv.
dist(D + 6) = n[0] * d * 2;
464 else bv.
dist(6) = n[0] * d * 2;
466 else if(n[1] == (S)0.0 && n[0] + n[2] == (S)0.0)
468 if(n[0] > 0) bv.
dist(D + 7) = n[0] * d * 2;
469 else bv.
dist(7) = n[0] * d * 2;
475 template <
typename S>
482 const S& d = new_s.
d;
484 const std::size_t D = 9;
486 for(std::size_t i = 0; i < D; ++i)
488 for(std::size_t i = D; i < 2 * D; ++i)
491 if(n[1] == (S)0.0 && n[2] == (S)0.0)
493 if(n[0] > 0) bv.
dist(D) = d;
494 else bv.
dist(0) = -d;
496 else if(n[0] == (S)0.0 && n[2] == (S)0.0)
498 if(n[1] > 0) bv.
dist(D + 1) = d;
499 else bv.
dist(1) = -d;
501 else if(n[0] == (S)0.0 && n[1] == (S)0.0)
503 if(n[2] > 0) bv.
dist(D + 2) = d;
504 else bv.
dist(2) = -d;
506 else if(n[2] == (S)0.0 && n[0] == n[1])
508 if(n[0] > 0) bv.
dist(D + 3) = n[0] * d * 2;
509 else bv.
dist(3) = n[0] * d * 2;
511 else if(n[1] == (S)0.0 && n[0] == n[2])
513 if(n[1] > 0) bv.
dist(D + 4) = n[0] * d * 2;
514 else bv.
dist(4) = n[0] * d * 2;
516 else if(n[0] == (S)0.0 && n[1] == n[2])
518 if(n[1] > 0) bv.
dist(D + 5) = n[1] * d * 2;
519 else bv.
dist(5) = n[1] * d * 2;
521 else if(n[2] == (S)0.0 && n[0] + n[1] == (S)0.0)
523 if(n[0] > 0) bv.
dist(D + 6) = n[0] * d * 2;
524 else bv.
dist(6) = n[0] * d * 2;
526 else if(n[1] == (S)0.0 && n[0] + n[2] == (S)0.0)
528 if(n[0] > 0) bv.
dist(D + 7) = n[0] * d * 2;
529 else bv.
dist(7) = n[0] * d * 2;
531 else if(n[0] == (S)0.0 && n[1] + n[2] == (S)0.0)
533 if(n[1] > 0) bv.
dist(D + 8) = n[1] * d * 2;
534 else bv.
dist(8) = n[1] * d * 2;
540 template <
typename S>
547 const S& d = new_s.
d;
549 const std::size_t D = 12;
551 for(std::size_t i = 0; i < D; ++i)
553 for(std::size_t i = D; i < 2 * D; ++i)
556 if(n[1] == (S)0.0 && n[2] == (S)0.0)
558 if(n[0] > 0) bv.
dist(D) = d;
559 else bv.
dist(0) = -d;
561 else if(n[0] == (S)0.0 && n[2] == (S)0.0)
563 if(n[1] > 0) bv.
dist(D + 1) = d;
564 else bv.
dist(1) = -d;
566 else if(n[0] == (S)0.0 && n[1] == (S)0.0)
568 if(n[2] > 0) bv.
dist(D + 2) = d;
569 else bv.
dist(2) = -d;
571 else if(n[2] == (S)0.0 && n[0] == n[1])
573 if(n[0] > 0) bv.
dist(D + 3) = n[0] * d * 2;
574 else bv.
dist(3) = n[0] * d * 2;
576 else if(n[1] == (S)0.0 && n[0] == n[2])
578 if(n[1] > 0) bv.
dist(D + 4) = n[0] * d * 2;
579 else bv.
dist(4) = n[0] * d * 2;
581 else if(n[0] == (S)0.0 && n[1] == n[2])
583 if(n[1] > 0) bv.
dist(D + 5) = n[1] * d * 2;
584 else bv.
dist(5) = n[1] * d * 2;
586 else if(n[2] == (S)0.0 && n[0] + n[1] == (S)0.0)
588 if(n[0] > 0) bv.
dist(D + 6) = n[0] * d * 2;
589 else bv.
dist(6) = n[0] * d * 2;
591 else if(n[1] == (S)0.0 && n[0] + n[2] == (S)0.0)
593 if(n[0] > 0) bv.
dist(D + 7) = n[0] * d * 2;
594 else bv.
dist(7) = n[0] * d * 2;
596 else if(n[0] == (S)0.0 && n[1] + n[2] == (S)0.0)
598 if(n[1] > 0) bv.
dist(D + 8) = n[1] * d * 2;
599 else bv.
dist(8) = n[1] * d * 2;
601 else if(n[0] + n[2] == (S)0.0 && n[0] + n[1] == (S)0.0)
603 if(n[0] > 0) bv.
dist(D + 9) = n[0] * d * 3;
604 else bv.
dist(9) = n[0] * d * 3;
606 else if(n[0] + n[1] == (S)0.0 && n[1] + n[2] == (S)0.0)
608 if(n[0] > 0) bv.
dist(D + 10) = n[0] * d * 3;
609 else bv.
dist(10) = n[0] * d * 3;
611 else if(n[0] + n[1] == (S)0.0 && n[0] + n[2] == (S)0.0)
613 if(n[1] > 0) bv.
dist(D + 11) = n[1] * d * 3;
614 else bv.
dist(11) = n[1] * d * 3;
620 template <
typename S>
627 const S& d = new_s.
d;
632 if(n[1] == (S)0.0 && n[2] == (S)0.0)
635 if(n[0] < 0) { bv_.
min_[0] = bv_.
max_[0] = -d; }
636 else if(n[0] > 0) { bv_.
min_[0] = bv_.
max_[0] = d; }
638 else if(n[0] == (S)0.0 && n[2] == (S)0.0)
641 if(n[1] < 0) { bv_.
min_[1] = bv_.
max_[1] = -d; }
642 else if(n[1] > 0) { bv_.
min_[1] = bv_.
max_[1] = d; }
644 else if(n[0] == (S)0.0 && n[1] == (S)0.0)
647 if(n[2] < 0) { bv_.
min_[2] = bv_.
max_[2] = -d; }
648 else if(n[2] > 0) { bv_.
min_[2] = bv_.
max_[2] = d; }
656 template <
typename S>
672 template <
typename S>
691 template <
typename S>
702 template <
typename S>
715 template <
typename S>
722 const S& d = new_s.
d;
724 const std::size_t D = 8;
726 for(std::size_t i = 0; i < D; ++i)
728 for(std::size_t i = D; i < 2 * D; ++i)
731 if(n[1] == (S)0.0 && n[2] == (S)0.0)
733 if(n[0] > 0) bv.
dist(0) = bv.
dist(D) = d;
736 else if(n[0] == (S)0.0 && n[2] == (S)0.0)
738 if(n[1] > 0) bv.
dist(1) = bv.
dist(D + 1) = d;
739 else bv.
dist(1) = bv.
dist(D + 1) = -d;
741 else if(n[0] == (S)0.0 && n[1] == (S)0.0)
743 if(n[2] > 0) bv.
dist(2) = bv.
dist(D + 2) = d;
744 else bv.
dist(2) = bv.
dist(D + 2) = -d;
746 else if(n[2] == (S)0.0 && n[0] == n[1])
748 bv.
dist(3) = bv.
dist(D + 3) = n[0] * d * 2;
750 else if(n[1] == (S)0.0 && n[0] == n[2])
752 bv.
dist(4) = bv.
dist(D + 4) = n[0] * d * 2;
754 else if(n[0] == (S)0.0 && n[1] == n[2])
756 bv.
dist(6) = bv.
dist(D + 5) = n[1] * d * 2;
758 else if(n[2] == (S)0.0 && n[0] + n[1] == (S)0.0)
760 bv.
dist(6) = bv.
dist(D + 6) = n[0] * d * 2;
762 else if(n[1] == (S)0.0 && n[0] + n[2] == (S)0.0)
764 bv.
dist(7) = bv.
dist(D + 7) = n[0] * d * 2;
770 template <
typename S>
777 const S& d = new_s.
d;
779 const std::size_t D = 9;
781 for(std::size_t i = 0; i < D; ++i)
783 for(std::size_t i = D; i < 2 * D; ++i)
786 if(n[1] == (S)0.0 && n[2] == (S)0.0)
788 if(n[0] > 0) bv.
dist(0) = bv.
dist(D) = d;
791 else if(n[0] == (S)0.0 && n[2] == (S)0.0)
793 if(n[1] > 0) bv.
dist(1) = bv.
dist(D + 1) = d;
794 else bv.
dist(1) = bv.
dist(D + 1) = -d;
796 else if(n[0] == (S)0.0 && n[1] == (S)0.0)
798 if(n[2] > 0) bv.
dist(2) = bv.
dist(D + 2) = d;
799 else bv.
dist(2) = bv.
dist(D + 2) = -d;
801 else if(n[2] == (S)0.0 && n[0] == n[1])
803 bv.
dist(3) = bv.
dist(D + 3) = n[0] * d * 2;
805 else if(n[1] == (S)0.0 && n[0] == n[2])
807 bv.
dist(4) = bv.
dist(D + 4) = n[0] * d * 2;
809 else if(n[0] == (S)0.0 && n[1] == n[2])
811 bv.
dist(5) = bv.
dist(D + 5) = n[1] * d * 2;
813 else if(n[2] == (S)0.0 && n[0] + n[1] == (S)0.0)
815 bv.
dist(6) = bv.
dist(D + 6) = n[0] * d * 2;
817 else if(n[1] == (S)0.0 && n[0] + n[2] == (S)0.0)
819 bv.
dist(7) = bv.
dist(D + 7) = n[0] * d * 2;
821 else if(n[0] == (S)0.0 && n[1] + n[2] == (S)0.0)
823 bv.
dist(8) = bv.
dist(D + 8) = n[1] * d * 2;
829 template <
typename S>
836 const S& d = new_s.
d;
838 const std::size_t D = 12;
840 for(std::size_t i = 0; i < D; ++i)
842 for(std::size_t i = D; i < 2 * D; ++i)
845 if(n[1] == (S)0.0 && n[2] == (S)0.0)
847 if(n[0] > 0) bv.
dist(0) = bv.
dist(D) = d;
850 else if(n[0] == (S)0.0 && n[2] == (S)0.0)
852 if(n[1] > 0) bv.
dist(1) = bv.
dist(D + 1) = d;
853 else bv.
dist(1) = bv.
dist(D + 1) = -d;
855 else if(n[0] == (S)0.0 && n[1] == (S)0.0)
857 if(n[2] > 0) bv.
dist(2) = bv.
dist(D + 2) = d;
858 else bv.
dist(2) = bv.
dist(D + 2) = -d;
860 else if(n[2] == (S)0.0 && n[0] == n[1])
862 bv.
dist(3) = bv.
dist(D + 3) = n[0] * d * 2;
864 else if(n[1] == (S)0.0 && n[0] == n[2])
866 bv.
dist(4) = bv.
dist(D + 4) = n[0] * d * 2;
868 else if(n[0] == (S)0.0 && n[1] == n[2])
870 bv.
dist(5) = bv.
dist(D + 5) = n[1] * d * 2;
872 else if(n[2] == (S)0.0 && n[0] + n[1] == (S)0.0)
874 bv.
dist(6) = bv.
dist(D + 6) = n[0] * d * 2;
876 else if(n[1] == (S)0.0 && n[0] + n[2] == (S)0.0)
878 bv.
dist(7) = bv.
dist(D + 7) = n[0] * d * 2;
880 else if(n[0] == (S)0.0 && n[1] + n[2] == (S)0.0)
882 bv.
dist(8) = bv.
dist(D + 8) = n[1] * d * 2;
884 else if(n[0] + n[2] == (S)0.0 && n[0] + n[1] == (S)0.0)
886 bv.
dist(9) = bv.
dist(D + 9) = n[0] * d * 3;
888 else if(n[0] + n[1] == (S)0.0 && n[1] + n[2] == (S)0.0)
890 bv.
dist(10) = bv.
dist(D + 10) = n[0] * d * 3;
892 else if(n[0] + n[1] == (S)0.0 && n[0] + n[2] == (S)0.0)
894 bv.
dist(11) = bv.
dist(D + 11) = n[1] * d * 3;
900 template <
typename S>
906 bv.
max_ = tf.translation() + v_delta;
907 bv.
min_ = tf.translation() - v_delta;
912 template <
typename S>
917 bv.
To = tf.translation();
918 bv.
axis.setIdentity();
924 template <
typename S>
935 struct ComputeBVImpl<double, AABB<double>,
Box<double>>;
939 struct ComputeBVImpl<double, OBB<double>,
Box<double>>;
951 struct ComputeBVImpl<double, AABB<double>,
Cone<double>>;
955 struct ComputeBVImpl<double, OBB<double>,
Cone<double>>;
1019 struct ComputeBVImpl<double, OBBRSS<double>,
Plane<double>>;
1027 struct ComputeBVImpl<double, KDOP<double, 16>,
Plane<double>>;
1031 struct ComputeBVImpl<double, KDOP<double, 18>,
Plane<double>>;
1035 struct ComputeBVImpl<double, KDOP<double, 24>,
Plane<double>>;
1054 template <
typename BV,
typename Shape>
1058 using S =
typename BV::S;
1064 template <
typename S>
1068 tf.linear().setIdentity();
1069 tf.translation() = bv.
center();
1073 template <
typename S>
1077 tf.linear() = bv.
axis;
1078 tf.translation() = bv.
To;
1082 template <
typename S>
1087 tf.translation() = bv.
obb.
To;
1091 template <
typename S>
1096 tf.translation() = bv.
obb.
To;
1100 template <
typename S>
1104 tf.linear() = bv.
axis;
1105 tf.translation() = bv.
To;
1109 template <
typename S>
1113 tf.linear().setIdentity();
1114 tf.translation() = bv.
center();
1118 template <
typename S>
1122 tf.linear().setIdentity();
1123 tf.translation() = bv.
center();
1127 template <
typename S>
1131 tf.linear().setIdentity();
1132 tf.translation() = bv.
center();
1136 template <
typename S>
1144 template <
typename S>
1150 tf.linear() = bv.
axis;
1151 tf.translation() = bv.
To;
1155 template <
typename S>
1160 tf.translation() = bv.
obb.
To;
1165 template <
typename S>
1172 tf.translation() = bv.
obb.
To;
1176 template <
typename S>
1180 tf.linear() = bv.
axis;
1181 tf.translation() = bv.
To;
1186 template <
typename S>
1194 template <
typename S>
1202 template <
typename S>