38 #ifndef FCL_BV_OBB_INL_H 39 #define FCL_BV_OBB_INL_H 41 #include "fcl/math/bv/OBB.h" 52 void computeVertices(
const OBB<double>& b, Vector3<double> vertices[8]);
56 OBB<double> merge_largedist(
const OBB<double>& b1,
const OBB<double>& b2);
60 OBB<double> merge_smalldist(
const OBB<double>& b1,
const OBB<double>& b2);
65 const Matrix3<double>& B,
66 const Vector3<double>& T,
67 const Vector3<double>& a,
68 const Vector3<double>& b);
73 const Transform3<double>& tf,
74 const Vector3<double>& a,
75 const Vector3<double>& b);
87 const Vector3<S>& center_,
88 const Vector3<S>& extent_)
89 : axis(axis_), To(center_), extent(extent_)
101 Vector3<S> t = other.
To -
To;
103 axis.col(0).dot(t),
axis.col(1).dot(t),
axis.col(2).dot(t));
104 Matrix3<S> R =
axis.transpose() * other.
axis;
110 template <
typename S>
117 template <
typename S>
120 Vector3<S> local_p = p -
To;
121 S proj = local_p.dot(
axis.col(0));
125 proj = local_p.dot(
axis.col(1));
129 proj = local_p.dot(
axis.col(2));
137 template <
typename S>
147 template <
typename S>
150 *
this = *
this + other;
156 template <
typename S>
159 Vector3<S> center_diff =
To - other.
To;
161 S max_extent2 = std::max(std::max(other.
extent[0], other.
extent[1]), other.
extent[2]);
162 if(center_diff.norm() > 2 * (max_extent + max_extent2))
164 return merge_largedist(*
this, other);
168 return merge_smalldist(*
this, other);
173 template <
typename S>
180 template <
typename S>
187 template <
typename S>
194 template <
typename S>
201 template <
typename S>
204 return extent.squaredNorm();
208 template <
typename S>
215 template <
typename S>
219 std::cerr <<
"OBB distance not implemented!" << std::endl;
224 template <
typename S>
225 void computeVertices(
const OBB<S>& b, Vector3<S> vertices[8])
228 const Vector3<S>&
To = b.
To;
230 Vector3<S> extAxis0 = b.
axis.col(0) * extent[0];
231 Vector3<S> extAxis1 = b.
axis.col(1) * extent[1];
232 Vector3<S> extAxis2 = b.
axis.col(2) * extent[2];
234 vertices[0] = To - extAxis0 - extAxis1 - extAxis2;
235 vertices[1] = To + extAxis0 - extAxis1 - extAxis2;
236 vertices[2] = To + extAxis0 + extAxis1 - extAxis2;
237 vertices[3] = To - extAxis0 + extAxis1 - extAxis2;
238 vertices[4] = To - extAxis0 - extAxis1 + extAxis2;
239 vertices[5] = To + extAxis0 - extAxis1 + extAxis2;
240 vertices[6] = To + extAxis0 + extAxis1 + extAxis2;
241 vertices[7] = To - extAxis0 + extAxis1 + extAxis2;
245 template <
typename S>
248 Vector3<S> vertex[16];
249 computeVertices(b1, vertex);
250 computeVertices(b2, vertex + 8);
253 Vector3<S> s(0, 0, 0);
257 b.
axis.col(0).normalize();
259 Vector3<S> vertex_proj[16];
260 for(
int i = 0; i < 16; ++i)
262 vertex_proj[i] = vertex[i];
263 vertex_proj[i].noalias() -= b.
axis.col(0) * vertex[i].dot(b.
axis.col(0));
266 getCovariance<S>(vertex_proj,
nullptr,
nullptr,
nullptr, 16, M);
286 else if (s[2] > s[max])
296 b.
axis.col(1) << E.col(0)[max], E.col(1)[max], E.col(2)[max];
297 b.
axis.col(2) << E.col(0)[mid], E.col(1)[mid], E.col(2)[mid];
300 getExtentAndCenter<S>(
301 vertex,
nullptr,
nullptr,
nullptr, 16, b.
axis, b.
To, b.
extent);
307 template <
typename S>
311 b.
To = (b1.
To + b2.
To) * 0.5;
312 Quaternion<S> q0(b1.
axis);
313 Quaternion<S> q1(b2.
axis);
315 q1.coeffs() = -q1.coeffs();
317 Quaternion<S> q(q0.coeffs() + q1.coeffs());
319 b.
axis = q.toRotationMatrix();
322 Vector3<S> vertex[8], diff;
323 S real_max = std::numeric_limits<S>::max();
324 Vector3<S> pmin(real_max, real_max, real_max);
325 Vector3<S> pmax(-real_max, -real_max, -real_max);
327 computeVertices(b1, vertex);
328 for(
int i = 0; i < 8; ++i)
330 diff = vertex[i] - b.
To;
331 for(
int j = 0; j < 3; ++j)
333 S dot = diff.dot(b.
axis.col(j));
336 else if(dot < pmin[j])
341 computeVertices(b2, vertex);
342 for(
int i = 0; i < 8; ++i)
344 diff = vertex[i] - b.
To;
345 for(
int j = 0; j < 3; ++j)
347 S dot = diff.dot(b.
axis.col(j));
350 else if(dot < pmin[j])
355 for(
int j = 0; j < 3; ++j)
357 b.
To += (b.
axis.col(j) * (0.5 * (pmax[j] + pmin[j])));
358 b.
extent[j] = 0.5 * (pmax[j] - pmin[j]);
365 template <
typename S,
typename Derived>
367 const OBB<S>& bv,
const Eigen::MatrixBase<Derived>& t)
375 template <
typename S,
typename DerivedA,
typename DerivedB>
376 bool overlap(
const Eigen::MatrixBase<DerivedA>& R0,
377 const Eigen::MatrixBase<DerivedB>& T0,
380 typename DerivedA::PlainObject R0b2 = R0 * b2.
axis;
381 typename DerivedA::PlainObject R = b1.
axis.transpose() * R0b2;
383 typename DerivedB::PlainObject Ttemp = R0 * b2.
To + T0 - b1.
To;
384 typename DerivedB::PlainObject T = Ttemp.transpose() * b1.
axis;
390 template <
typename S>
391 bool obbDisjoint(
const Matrix3<S>& B,
const Vector3<S>& T,
392 const Vector3<S>& a,
const Vector3<S>& b)
397 Matrix3<S> Bf = B.cwiseAbs();
403 t = ((T[0] < 0.0) ? -T[0] : T[0]);
405 if(t > (a[0] + Bf.row(0).dot(b)))
410 t = ((s < 0.0) ? -s : s);
412 if(t > (b[0] + Bf.col(0).dot(a)))
416 t = ((T[1] < 0.0) ? -T[1] : T[1]);
418 if(t > (a[1] + Bf.row(1).dot(b)))
422 t =((T[2] < 0.0) ? -T[2] : T[2]);
424 if(t > (a[2] + Bf.row(2).dot(b)))
429 t = ((s < 0.0) ? -s : s);
431 if(t > (b[1] + Bf.col(1).dot(a)))
436 t = ((s < 0.0) ? -s : s);
438 if(t > (b[2] + Bf.col(2).dot(a)))
442 s = T[2] * B(1, 0) - T[1] * B(2, 0);
443 t = ((s < 0.0) ? -s : s);
445 if(t > (a[1] * Bf(2, 0) + a[2] * Bf(1, 0) +
446 b[1] * Bf(0, 2) + b[2] * Bf(0, 1)))
450 s = T[2] * B(1, 1) - T[1] * B(2, 1);
451 t = ((s < 0.0) ? -s : s);
453 if(t > (a[1] * Bf(2, 1) + a[2] * Bf(1, 1) +
454 b[0] * Bf(0, 2) + b[2] * Bf(0, 0)))
458 s = T[2] * B(1, 2) - T[1] * B(2, 2);
459 t = ((s < 0.0) ? -s : s);
461 if(t > (a[1] * Bf(2, 2) + a[2] * Bf(1, 2) +
462 b[0] * Bf(0, 1) + b[1] * Bf(0, 0)))
466 s = T[0] * B(2, 0) - T[2] * B(0, 0);
467 t = ((s < 0.0) ? -s : s);
469 if(t > (a[0] * Bf(2, 0) + a[2] * Bf(0, 0) +
470 b[1] * Bf(1, 2) + b[2] * Bf(1, 1)))
474 s = T[0] * B(2, 1) - T[2] * B(0, 1);
475 t = ((s < 0.0) ? -s : s);
477 if(t > (a[0] * Bf(2, 1) + a[2] * Bf(0, 1) +
478 b[0] * Bf(1, 2) + b[2] * Bf(1, 0)))
482 s = T[0] * B(2, 2) - T[2] * B(0, 2);
483 t = ((s < 0.0) ? -s : s);
485 if(t > (a[0] * Bf(2, 2) + a[2] * Bf(0, 2) +
486 b[0] * Bf(1, 1) + b[1] * Bf(1, 0)))
490 s = T[1] * B(0, 0) - T[0] * B(1, 0);
491 t = ((s < 0.0) ? -s : s);
493 if(t > (a[0] * Bf(1, 0) + a[1] * Bf(0, 0) +
494 b[1] * Bf(2, 2) + b[2] * Bf(2, 1)))
498 s = T[1] * B(0, 1) - T[0] * B(1, 1);
499 t = ((s < 0.0) ? -s : s);
501 if(t > (a[0] * Bf(1, 1) + a[1] * Bf(0, 1) +
502 b[0] * Bf(2, 2) + b[2] * Bf(2, 0)))
506 s = T[1] * B(0, 2) - T[0] * B(1, 2);
507 t = ((s < 0.0) ? -s : s);
509 if(t > (a[0] * Bf(1, 2) + a[1] * Bf(0, 2) +
510 b[0] * Bf(2, 1) + b[1] * Bf(2, 0)))
518 template <
typename S>
520 const Transform3<S>& tf,
527 Matrix3<S> Bf = tf.linear().cwiseAbs();
533 t = ((tf.translation()[0] < 0.0) ? -tf.translation()[0] : tf.translation()[0]);
535 if(t > (a[0] + Bf.row(0).dot(b)))
539 s = tf.linear().col(0).dot(tf.translation());
540 t = ((s < 0.0) ? -s : s);
542 if(t > (b[0] + Bf.col(0).dot(a)))
546 t = ((tf.translation()[1] < 0.0) ? -tf.translation()[1] : tf.translation()[1]);
548 if(t > (a[1] + Bf.row(1).dot(b)))
552 t =((tf.translation()[2] < 0.0) ? -tf.translation()[2] : tf.translation()[2]);
554 if(t > (a[2] + Bf.row(2).dot(b)))
558 s = tf.linear().col(1).dot(tf.translation());
559 t = ((s < 0.0) ? -s : s);
561 if(t > (b[1] + Bf.col(1).dot(a)))
565 s = tf.linear().col(2).dot(tf.translation());
566 t = ((s < 0.0) ? -s : s);
568 if(t > (b[2] + Bf.col(2).dot(a)))
572 s = tf.translation()[2] * tf.linear()(1, 0) - tf.translation()[1] * tf.linear()(2, 0);
573 t = ((s < 0.0) ? -s : s);
575 if(t > (a[1] * Bf(2, 0) + a[2] * Bf(1, 0) +
576 b[1] * Bf(0, 2) + b[2] * Bf(0, 1)))
580 s = tf.translation()[2] * tf.linear()(1, 1) - tf.translation()[1] * tf.linear()(2, 1);
581 t = ((s < 0.0) ? -s : s);
583 if(t > (a[1] * Bf(2, 1) + a[2] * Bf(1, 1) +
584 b[0] * Bf(0, 2) + b[2] * Bf(0, 0)))
588 s = tf.translation()[2] * tf.linear()(1, 2) - tf.translation()[1] * tf.linear()(2, 2);
589 t = ((s < 0.0) ? -s : s);
591 if(t > (a[1] * Bf(2, 2) + a[2] * Bf(1, 2) +
592 b[0] * Bf(0, 1) + b[1] * Bf(0, 0)))
596 s = tf.translation()[0] * tf.linear()(2, 0) - tf.translation()[2] * tf.linear()(0, 0);
597 t = ((s < 0.0) ? -s : s);
599 if(t > (a[0] * Bf(2, 0) + a[2] * Bf(0, 0) +
600 b[1] * Bf(1, 2) + b[2] * Bf(1, 1)))
604 s = tf.translation()[0] * tf.linear()(2, 1) - tf.translation()[2] * tf.linear()(0, 1);
605 t = ((s < 0.0) ? -s : s);
607 if(t > (a[0] * Bf(2, 1) + a[2] * Bf(0, 1) +
608 b[0] * Bf(1, 2) + b[2] * Bf(1, 0)))
612 s = tf.translation()[0] * tf.linear()(2, 2) - tf.translation()[2] * tf.linear()(0, 2);
613 t = ((s < 0.0) ? -s : s);
615 if(t > (a[0] * Bf(2, 2) + a[2] * Bf(0, 2) +
616 b[0] * Bf(1, 1) + b[1] * Bf(1, 0)))
620 s = tf.translation()[1] * tf.linear()(0, 0) - tf.translation()[0] * tf.linear()(1, 0);
621 t = ((s < 0.0) ? -s : s);
623 if(t > (a[0] * Bf(1, 0) + a[1] * Bf(0, 0) +
624 b[1] * Bf(2, 2) + b[2] * Bf(2, 1)))
628 s = tf.translation()[1] * tf.linear()(0, 1) - tf.translation()[0] * tf.linear()(1, 1);
629 t = ((s < 0.0) ? -s : s);
631 if(t > (a[0] * Bf(1, 1) + a[1] * Bf(0, 1) +
632 b[0] * Bf(2, 2) + b[2] * Bf(2, 0)))
636 s = tf.translation()[1] * tf.linear()(0, 2) - tf.translation()[0] * tf.linear()(1, 2);
637 t = ((s < 0.0) ? -s : s);
639 if(t > (a[0] * Bf(1, 2) + a[1] * Bf(0, 2) +
640 b[0] * Bf(2, 1) + b[1] * Bf(2, 0)))
S volume() const
Volume of the OBB.
Definition: OBB-inl.h:195
OBB< S > & operator+=(const Vector3< S > &p)
A simple way to merge the OBB and a point (the result is not compact).
Definition: OBB-inl.h:138
Main namespace.
Definition: broadphase_bruteforce-inl.h:45
S distance(const OBB &other, Vector3< S > *P=nullptr, Vector3< S > *Q=nullptr) const
Distance between two OBBs, not implemented.
Definition: OBB-inl.h:216
AABB< S > translate(const AABB< S > &aabb, const Eigen::MatrixBase< Derived > &t)
translate the center of AABB by t
Definition: AABB-inl.h:345
bool contain(const Vector3< S > &p) const
Check whether the OBB contains a point.
Definition: OBB-inl.h:118
S width() const
Width of the OBB.
Definition: OBB-inl.h:174
bool overlap(const OBB< S > &other) const
Check collision between two OBB, return true if collision happens.
Definition: OBB-inl.h:96
OBB< S > operator+(const OBB< S > &other) const
Return the merged OBB of current OBB and the other one (the result is not compact).
Definition: OBB-inl.h:157
Vector3< S > extent
Half dimensions of OBB.
Definition: OBB.h:68
Matrix3< S > axis
Orientation of OBB. The axes of the rotation matrix are the principle directions of the box...
Definition: OBB.h:62
S size() const
Size of the OBB (used in BV_Splitter to order two OBBs)
Definition: OBB-inl.h:202
const Vector3< S > center() const
Center of the OBB.
Definition: OBB-inl.h:209
S depth() const
Depth of the OBB.
Definition: OBB-inl.h:188
OBB()
Constructor.
Definition: OBB-inl.h:79
Vector3< S > To
Center of OBB.
Definition: OBB.h:65
S height() const
Height of the OBB.
Definition: OBB-inl.h:181
Oriented bounding box class.
Definition: OBB.h:51