38 #ifndef FCL_NARROWPHASE_DETAIL_BOXBOX_INL_H 
   39 #define FCL_NARROWPHASE_DETAIL_BOXBOX_INL_H 
   54                          const Vector3<double>& pb, 
const Vector3<double>& ub,
 
   55                          double* alpha, 
double* beta);
 
   63 void cullPoints2(
int n, 
double p[], 
int m, 
int i0, 
int iret[]);
 
   68     const Vector3<double>& side1,
 
   69     const Transform3<double>& tf1,
 
   70     const Vector3<double>& side2,
 
   71     const Transform3<double>& tf2,
 
   72     Vector3<double>& normal,
 
   76     std::vector<ContactPoint<double>>& contacts);
 
   81                      const Box<double>& s2, 
const Transform3<double>& tf2,
 
   82                      std::vector<ContactPoint<double>>* contacts_);
 
   94   S d = 1 - uaub * uaub;
 
  103     *alpha = (q1 + uaub * q2) * d;
 
  104     *beta = (uaub * q1 + q2) * d;
 
  109 template <
typename S>
 
  118   for(
int dir = 0; dir <= 1; ++dir)
 
  121     for(
int sign = -1; sign <= 1; sign += 2)
 
  127       for(
int i = nq; i > 0; --i)
 
  130         if(sign * pq[dir] < h[dir])
 
  143         S* nextq = (i > 1) ? pq+2 : q;
 
  144         if((sign*pq[dir] < h[dir]) ^ (sign*nextq[dir] < h[dir]))
 
  147           pr[1-dir] = pq[1-dir] + (nextq[1-dir]-pq[1-dir]) /
 
  148             (nextq[dir]-pq[dir]) * (sign*h[dir]-pq[dir]);
 
  149           pr[dir] = sign*h[dir];
 
  161       r = (q == ret) ? buffer : ret;
 
  167   if(q != ret) memcpy(ret, q, nr*2*
sizeof(S));
 
  172 template <
typename S>
 
  184     cx = 0.5 * (p[0] + p[2]);
 
  185     cy = 0.5 * (p[1] + p[3]);
 
  191     for(
int i = 0; i < n-1; ++i)
 
  193       q = p[i*2]*p[i*2+3] - p[i*2+2]*p[i*2+1];
 
  195       cx += q*(p[i*2]+p[i*2+2]);
 
  196       cy += q*(p[i*2+1]+p[i*2+3]);
 
  198     q = p[n*2-2]*p[1] - p[0]*p[n*2-1];
 
  204     cx = a*(cx + q*(p[n*2-2]+p[0]));
 
  205     cy = a*(cy + q*(p[n*2-1]+p[1]));
 
  211   for(
int i = 0; i < n; ++i)
 
  212     A[i] = atan2(p[i*2+1]-cy,p[i*2]-cx);
 
  216   for(
int i = 0; i < n; ++i) avail[i] = 1;
 
  221   for(
int j = 1; j < m; ++j)
 
  223     a = j*(2*pi/m) + A[i0];
 
  224     if (a > pi) a -= 2*pi;
 
  225     S maxdiff= 1e9, diff;
 
  228     for(
int i = 0; i < n; ++i)
 
  232         diff = std::abs(A[i]-a);
 
  233         if(diff > pi) diff = 2*pi - diff;
 
  247 template <
typename S, 
typename DerivedA, 
typename DerivedB>
 
  250     const Eigen::MatrixBase<DerivedA>& R1,
 
  251     const Eigen::MatrixBase<DerivedB>& T1,
 
  253     const Eigen::MatrixBase<DerivedA>& R2,
 
  254     const Eigen::MatrixBase<DerivedB>& T2,
 
  264   const S fudge_factor = S(1.05);
 
  267   int invert_normal, code;
 
  290   int best_col_id = -1;
 
  291   const Eigen::MatrixBase<DerivedA>* normalR = 0;
 
  300   s2 = std::abs(tmp) - (Q.row(0).dot(B) + A[0]);
 
  301   if(s2 > 0) { *return_code = 0; 
return 0; }
 
  307     invert_normal = (tmp < 0);
 
  312   s2 = std::abs(tmp) - (Q.row(1).dot(B) + A[1]);
 
  313   if(s2 > 0) { *return_code = 0; 
return 0; }
 
  319     invert_normal = (tmp < 0);
 
  324   s2 = std::abs(tmp) - (Q.row(2).dot(B) + A[2]);
 
  325   if(s2 > 0) { *return_code = 0; 
return 0; }
 
  331     invert_normal = (tmp < 0);
 
  336   tmp = R2.col(0).dot(p);
 
  337   s2 = std::abs(tmp) - (Q.col(0).dot(A) + B[0]);
 
  338   if(s2 > 0) { *return_code = 0; 
return 0; }
 
  344     invert_normal = (tmp < 0);
 
  348   tmp = R2.col(1).dot(p);
 
  349   s2 = std::abs(tmp) - (Q.col(1).dot(A) + B[1]);
 
  350   if(s2 > 0) { *return_code = 0; 
return 0; }
 
  356     invert_normal = (tmp < 0);
 
  360   tmp = R2.col(2).dot(p);
 
  361   s2 =  std::abs(tmp) - (Q.col(2).dot(A) + B[2]);
 
  362   if(s2 > 0) { *return_code = 0; 
return 0; }
 
  368     invert_normal = (tmp < 0);
 
  396     S scale_factor = 
max(
max(A.maxCoeff(), B.maxCoeff()), S(1.0)) * S(10) * eps;
 
  397     Q.array() += scale_factor;
 
  403   tmp = pp[2] * R(1, 0) - pp[1] * R(2, 0);
 
  404   s2 = std::abs(tmp) - (A[1] * Q(2, 0) + A[2] * Q(1, 0) + B[1] * Q(0, 2) + B[2] * Q(0, 1));
 
  405   if(s2 > 0) { *return_code = 0; 
return 0; }
 
  411     if(s2 * fudge_factor > s)
 
  416       invert_normal = (tmp < 0);
 
  421   tmp = pp[2] * R(1, 1) - pp[1] * R(2, 1);
 
  422   s2 = std::abs(tmp) - (A[1] * Q(2, 1) + A[2] * Q(1, 1) + B[0] * Q(0, 2) + B[2] * Q(0, 0));
 
  423   if(s2 > 0) { *return_code = 0; 
return 0; }
 
  429     if(s2 * fudge_factor > s)
 
  434       invert_normal = (tmp < 0);
 
  439   tmp = pp[2] * R(1, 2) - pp[1] * R(2, 2);
 
  440   s2 = std::abs(tmp) - (A[1] * Q(2, 2) + A[2] * Q(1, 2) + B[0] * Q(0, 1) + B[1] * Q(0, 0));
 
  441   if(s2 > 0) { *return_code = 0; 
return 0; }
 
  447     if(s2 * fudge_factor > s)
 
  452       invert_normal = (tmp < 0);
 
  458   tmp = pp[0] * R(2, 0) - pp[2] * R(0, 0);
 
  459   s2 = std::abs(tmp) - (A[0] * Q(2, 0) + A[2] * Q(0, 0) + B[1] * Q(1, 2) + B[2] * Q(1, 1));
 
  460   if(s2 > 0) { *return_code = 0; 
return 0; }
 
  466     if(s2 * fudge_factor > s)
 
  471       invert_normal = (tmp < 0);
 
  476   tmp = pp[0] * R(2, 1) - pp[2] * R(0, 1);
 
  477   s2 = std::abs(tmp) - (A[0] * Q(2, 1) + A[2] * Q(0, 1) + B[0] * Q(1, 2) + B[2] * Q(1, 0));
 
  478   if(s2 > 0) { *return_code = 0; 
return 0; }
 
  484     if(s2 * fudge_factor > s)
 
  489       invert_normal = (tmp < 0);
 
  494   tmp = pp[0] * R(2, 2) - pp[2] * R(0, 2);
 
  495   s2 = std::abs(tmp) - (A[0] * Q(2, 2) + A[2] * Q(0, 2) + B[0] * Q(1, 1) + B[1] * Q(1, 0));
 
  496   if(s2 > 0) { *return_code = 0; 
return 0; }
 
  502     if(s2 * fudge_factor > s)
 
  507       invert_normal = (tmp < 0);
 
  513   tmp = pp[1] * R(0, 0) - pp[0] * R(1, 0);
 
  514   s2 = std::abs(tmp) - (A[0] * Q(1, 0) + A[1] * Q(0, 0) + B[1] * Q(2, 2) + B[2] * Q(2, 1));
 
  515   if(s2 > 0) { *return_code = 0; 
return 0; }
 
  521     if(s2 * fudge_factor > s)
 
  526       invert_normal = (tmp < 0);
 
  531   tmp = pp[1] * R(0, 1) - pp[0] * R(1, 1);
 
  532   s2 = std::abs(tmp) - (A[0] * Q(1, 1) + A[1] * Q(0, 1) + B[0] * Q(2, 2) + B[2] * Q(2, 0));
 
  533   if(s2 > 0) { *return_code = 0; 
return 0; }
 
  539     if(s2 * fudge_factor > s)
 
  544       invert_normal = (tmp < 0);
 
  549   tmp = pp[1] * R(0, 2) - pp[0] * R(1, 2);
 
  550   s2 = std::abs(tmp) - (A[0] * Q(1, 2) + A[1] * Q(0, 2) + B[0] * Q(2, 1) + B[1] * Q(2, 0));
 
  551   if(s2 > 0) { *return_code = 0; 
return 0; }
 
  557     if(s2 * fudge_factor > s)
 
  562       invert_normal = (tmp < 0);
 
  567   if (!code) { *return_code = code; 
return 0; }
 
  571   if(best_col_id != -1)
 
  572     normal = normalR->col(best_col_id);
 
  574     normal = R1 * normalC;
 
  590     for(
int j = 0; j < 3; ++j)
 
  592       sign = (R1.col(j).dot(normal) > 0) ? 1 : -1;
 
  593       pa += R1.col(j) * (A[j] * sign);
 
  599     for(
int j = 0; j < 3; ++j)
 
  601       sign = (R2.col(j).dot(normal) > 0) ? -1 : 1;
 
  602       pb += R2.col(j) * (B[j] * sign);
 
  614     contacts.emplace_back(normal, pointInWorld, *depth);
 
  625   const Eigen::MatrixBase<DerivedA> *Ra, *Rb;
 
  626   const Eigen::MatrixBase<DerivedB> *pa, *pb;
 
  656   nr = Rb->transpose() * normal2;
 
  697     center = (*pb) - (*pa) + Rb->col(lanr) * ((*Sb)[lanr]);
 
  699     center = (*pb) - (*pa) - Rb->col(lanr) * ((*Sb)[lanr]);
 
  702   int codeN, code1, code2;
 
  725   S c1, c2, m11, m12, m21, m22;
 
  726   c1 = Ra->col(code1).dot(center);
 
  727   c2 = Ra->col(code2).dot(center);
 
  732   m11 = Rb->col(a1).dot(tempRac);
 
  733   m12 = Rb->col(a2).dot(tempRac);
 
  734   tempRac = Ra->col(code2);
 
  735   m21 = Rb->col(a1).dot(tempRac);
 
  736   m22 = Rb->col(a2).dot(tempRac);
 
  738   S k1 = m11 * (*Sb)[a1];
 
  739   S k2 = m21 * (*Sb)[a1];
 
  740   S k3 = m12 * (*Sb)[a2];
 
  741   S k4 = m22 * (*Sb)[a2];
 
  742   quad[0] = c1 - k1 - k3;
 
  743   quad[1] = c2 - k2 - k4;
 
  744   quad[2] = c1 - k1 + k3;
 
  745   quad[3] = c2 - k2 + k4;
 
  746   quad[4] = c1 + k1 + k3;
 
  747   quad[5] = c2 + k2 + k4;
 
  748   quad[6] = c1 + k1 - k3;
 
  749   quad[7] = c2 + k2 - k4;
 
  753   rect[0] = (*Sa)[code1];
 
  754   rect[1] = (*Sa)[code2];
 
  759   if(n_intersect < 1) { *return_code = code; 
return 0; } 
 
  767   S det1 = 1.f/(m11*m22 - m12*m21);
 
  773   for(
int j = 0; j < n_intersect; ++j)
 
  775     S k1 =  m22*(ret[j*2]-c1) - m12*(ret[j*2+1]-c2);
 
  776     S k2 = -m21*(ret[j*2]-c1) + m11*(ret[j*2+1]-c2);
 
  777     points[cnum] = center + Rb->col(a1) * k1 + Rb->col(a2) * k2;
 
  778     dep[cnum] = (*Sa)[codeN] - normal2.dot(points[cnum]);
 
  781       ret[cnum*2] = ret[j*2];
 
  782       ret[cnum*2+1] = ret[j*2+1];
 
  786   if(cnum < 1) { *return_code = code; 
return 0; } 
 
  789   if(maxc > cnum) maxc = cnum;
 
  790   if(maxc < 1) maxc = 1;
 
  801   int iret[] = {0, 1, 2, 3, 4, 5, 6, 7};
 
  805     for(
int i = 1; i < cnum; ++i)
 
  807       if(dep[i] > maxdepth)
 
  819     for(
int j = 0; j < cnum; ++j)
 
  822       Vector3<S> pointInWorld = points[i] + (*pa) + normal * (dep[i] / 2);
 
  823       contacts.emplace_back(normal, pointInWorld, dep[i]);
 
  826     for(
int j = 0; j < cnum; ++j)
 
  829       Vector3<S> pointInWorld = points[i] + (*pa) - normal * (dep[i] / 2);
 
  830       contacts.emplace_back(normal, pointInWorld, dep[i]);
 
  839 template <
typename S>
 
  851   return boxBox2(side1, tf1.linear(), tf1.translation(), side2, tf2.linear(),
 
  852                  tf2.translation(), normal, depth, return_code, maxc, contacts);
 
  856 template <
typename S>
 
  861   std::vector<ContactPoint<S>> contacts;
 
  867                            normal, &depth, &return_code,
 
  871     *contacts_ = contacts;
 
  873   return return_code != 0;