BV_fitter.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2011, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Willow Garage, Inc. nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  */
00034 
00037 #include "fcl/BVH/BV_fitter.h"
00038 #include "fcl/BVH/BVH_utility.h"
00039 #include <limits>
00040 
00041 namespace fcl
00042 {
00043 
00044 
00045 static const double kIOS_RATIO = 1.5;
00046 static const double invSinA = 2;
00047 static const double invCosA = 2.0 / sqrt(3.0);
00048 static const double sinA = 0.5;
00049 static const double cosA = sqrt(3.0) / 2.0;
00050 
00051 static inline void axisFromEigen(Vec3f eigenV[3], Matrix3f::U eigenS[3], Vec3f axis[3])
00052 {
00053   int min, mid, max;
00054   if(eigenS[0] > eigenS[1]) { max = 0; min = 1; }
00055   else { min = 0; max = 1; }
00056   if(eigenS[2] < eigenS[min]) { mid = min; min = 2; }
00057   else if(eigenS[2] > eigenS[max]) { mid = max; max = 2; }
00058   else { mid = 2; }
00059 
00060   axis[0].setValue(eigenV[0][max], eigenV[1][max], eigenV[2][max]);
00061   axis[1].setValue(eigenV[0][mid], eigenV[1][mid], eigenV[2][mid]);
00062   axis[2].setValue(eigenV[1][max]*eigenV[2][mid] - eigenV[1][mid]*eigenV[2][max],
00063                    eigenV[0][mid]*eigenV[2][max] - eigenV[0][max]*eigenV[2][mid],
00064                    eigenV[0][max]*eigenV[1][mid] - eigenV[0][mid]*eigenV[1][max]);
00065 }
00066 
00067 namespace OBB_fit_functions
00068 {
00069 
00070 void fit1(Vec3f* ps, OBB& bv)
00071 {
00072   bv.To = ps[0];
00073   bv.axis[0].setValue(1, 0, 0);
00074   bv.axis[1].setValue(0, 1, 0);
00075   bv.axis[2].setValue(0, 0, 1);
00076   bv.extent.setValue(0);
00077 }
00078 
00079 void fit2(Vec3f* ps, OBB& bv)
00080 {
00081   const Vec3f& p1 = ps[0];
00082   const Vec3f& p2 = ps[1];
00083   Vec3f p1p2 = p1 - p2;
00084   FCL_REAL len_p1p2 = p1p2.length();
00085   p1p2.normalize();
00086 
00087   bv.axis[0] = p1p2;
00088   generateCoordinateSystem(bv.axis[0], bv.axis[1], bv.axis[2]);
00089 
00090   bv.extent.setValue(len_p1p2 * 0.5, 0, 0);
00091   bv.To.setValue(0.5 * (p1[0] + p2[0]),
00092                  0.5 * (p1[1] + p2[1]),
00093                  0.5 * (p1[2] + p2[2]));
00094 }
00095 
00096 void fit3(Vec3f* ps, OBB& bv)
00097 {
00098   const Vec3f& p1 = ps[0];
00099   const Vec3f& p2 = ps[1];
00100   const Vec3f& p3 = ps[2];
00101   Vec3f e[3];
00102   e[0] = p1 - p2;
00103   e[1] = p2 - p3;
00104   e[2] = p3 - p1;
00105   FCL_REAL len[3];
00106   len[0] = e[0].sqrLength();
00107   len[1] = e[1].sqrLength();
00108   len[2] = e[2].sqrLength();
00109 
00110   int imax = 0;
00111   if(len[1] > len[0]) imax = 1;
00112   if(len[2] > len[imax]) imax = 2;
00113 
00114   Vec3f& u = bv.axis[0];
00115   Vec3f& v = bv.axis[1];
00116   Vec3f& w = bv.axis[2];
00117 
00118   w = e[0].cross(e[1]);
00119   w.normalize();
00120   u = e[imax];
00121   u.normalize();
00122   v = w.cross(u);
00123 
00124   getExtentAndCenter(ps, NULL, NULL, NULL, 3, bv.axis, bv.To, bv.extent);
00125 }
00126 
00127 void fit6(Vec3f* ps, OBB& bv)
00128 {
00129   OBB bv1, bv2;
00130   fit3(ps, bv1);
00131   fit3(ps + 3, bv2);
00132   bv = bv1 + bv2;
00133 }
00134 
00135 
00136 void fitn(Vec3f* ps, int n, OBB& bv)
00137 {
00138   Matrix3f M;
00139   Vec3f E[3];
00140   Matrix3f::U s[3] = {0, 0, 0}; // three eigen values
00141 
00142   getCovariance(ps, NULL, NULL, NULL, n, M);
00143   eigen(M, s, E);
00144   axisFromEigen(E, s, bv.axis);
00145 
00146   // set obb centers and extensions
00147   getExtentAndCenter(ps, NULL, NULL, NULL, n, bv.axis, bv.To, bv.extent);
00148 }
00149 
00150 }
00151 
00152 
00153 namespace RSS_fit_functions
00154 {
00155 void fit1(Vec3f* ps, RSS& bv)
00156 {
00157   bv.Tr = ps[0];
00158   bv.axis[0].setValue(1, 0, 0);
00159   bv.axis[1].setValue(0, 1, 0);
00160   bv.axis[2].setValue(0, 0, 1);
00161   bv.l[0] = 0;
00162   bv.l[1] = 0;
00163   bv.r = 0;
00164 }
00165 
00166 void fit2(Vec3f* ps, RSS& bv)
00167 {
00168   const Vec3f& p1 = ps[0];
00169   const Vec3f& p2 = ps[1];
00170   Vec3f p1p2 = p1 - p2;
00171   FCL_REAL len_p1p2 = p1p2.length();
00172   p1p2.normalize();
00173 
00174   bv.axis[0] = p1p2;
00175   generateCoordinateSystem(bv.axis[0], bv.axis[1], bv.axis[2]);
00176   bv.l[0] = len_p1p2;
00177   bv.l[1] = 0;
00178 
00179   bv.Tr = p2;
00180   bv.r = 0;
00181 }
00182 
00183 void fit3(Vec3f* ps, RSS& bv)
00184 {
00185   const Vec3f& p1 = ps[0];
00186   const Vec3f& p2 = ps[1];
00187   const Vec3f& p3 = ps[2];
00188   Vec3f e[3];
00189   e[0] = p1 - p2;
00190   e[1] = p2 - p3;
00191   e[2] = p3 - p1;
00192   FCL_REAL len[3];
00193   len[0] = e[0].sqrLength();
00194   len[1] = e[1].sqrLength();
00195   len[2] = e[2].sqrLength();
00196 
00197   int imax = 0;
00198   if(len[1] > len[0]) imax = 1;
00199   if(len[2] > len[imax]) imax = 2;
00200 
00201   Vec3f& u = bv.axis[0];
00202   Vec3f& v = bv.axis[1];
00203   Vec3f& w = bv.axis[2];
00204 
00205   w = e[0].cross(e[1]);
00206   w.normalize();
00207   u = e[imax];
00208   u.normalize();
00209   v = w.cross(u);
00210 
00211   getRadiusAndOriginAndRectangleSize(ps, NULL, NULL, NULL, 3, bv.axis, bv.Tr, bv.l, bv.r);
00212 }
00213 
00214 void fit6(Vec3f* ps, RSS& bv)
00215 {
00216   RSS bv1, bv2;
00217   fit3(ps, bv1);
00218   fit3(ps + 3, bv2);
00219   bv = bv1 + bv2;
00220 }
00221 
00222 void fitn(Vec3f* ps, int n, RSS& bv)
00223 {
00224   Matrix3f M; // row first matrix
00225   Vec3f E[3]; // row first eigen-vectors
00226   Matrix3f::U s[3] = {0, 0, 0};
00227 
00228   getCovariance(ps, NULL, NULL, NULL, n, M);
00229   eigen(M, s, E);
00230   axisFromEigen(E, s, bv.axis);
00231 
00232   // set rss origin, rectangle size and radius
00233   getRadiusAndOriginAndRectangleSize(ps, NULL, NULL, NULL, n, bv.axis, bv.Tr, bv.l, bv.r);
00234 }
00235 
00236 }
00237 
00238 namespace kIOS_fit_functions
00239 {
00240 
00241 void fit1(Vec3f* ps, kIOS& bv)
00242 {
00243   bv.num_spheres = 1;
00244   bv.spheres[0].o = ps[0];
00245   bv.spheres[0].r = 0;
00246 
00247   bv.obb.axis[0].setValue(1, 0, 0);
00248   bv.obb.axis[1].setValue(0, 1, 0);
00249   bv.obb.axis[2].setValue(0, 0, 1);
00250   bv.obb.extent.setValue(0);
00251   bv.obb.To = ps[0];
00252 }
00253 
00254 void fit2(Vec3f* ps, kIOS& bv)
00255 {
00256   bv.num_spheres = 5;
00257 
00258   const Vec3f& p1 = ps[0];
00259   const Vec3f& p2 = ps[1];
00260   Vec3f p1p2 = p1 - p2;
00261   FCL_REAL len_p1p2 = p1p2.length();
00262   p1p2.normalize();
00263  
00264   Vec3f* axis = bv.obb.axis;
00265   axis[0] = p1p2;
00266   generateCoordinateSystem(axis[0], axis[1], axis[2]);
00267     
00268   FCL_REAL r0 = len_p1p2 * 0.5;
00269   bv.obb.extent.setValue(r0, 0, 0);
00270   bv.obb.To = (p1 + p2) * 0.5;
00271 
00272   bv.spheres[0].o = bv.obb.To;
00273   bv.spheres[0].r = r0;
00274 
00275   FCL_REAL r1 = r0 * invSinA;
00276   FCL_REAL r1cosA = r1 * cosA;
00277   bv.spheres[1].r = r1;
00278   bv.spheres[2].r = r1;
00279   Vec3f delta = axis[1] * r1cosA;
00280   bv.spheres[1].o = bv.spheres[0].o - delta;
00281   bv.spheres[2].o = bv.spheres[0].o + delta;
00282 
00283   bv.spheres[3].r = r1;
00284   bv.spheres[4].r = r1;
00285   delta = axis[2] * r1cosA;
00286   bv.spheres[3].o = bv.spheres[0].o - delta;
00287   bv.spheres[4].o = bv.spheres[0].o + delta;
00288 }
00289 
00290 void fit3(Vec3f* ps, kIOS& bv)
00291 {
00292   bv.num_spheres = 3;
00293     
00294   const Vec3f& p1 = ps[0];
00295   const Vec3f& p2 = ps[1];
00296   const Vec3f& p3 = ps[2];
00297   Vec3f e[3];
00298   e[0] = p1 - p2;
00299   e[1] = p2 - p3;
00300   e[2] = p3 - p1;
00301   FCL_REAL len[3];
00302   len[0] = e[0].sqrLength();
00303   len[1] = e[1].sqrLength();
00304   len[2] = e[2].sqrLength();
00305     
00306   int imax = 0;
00307   if(len[1] > len[0]) imax = 1;
00308   if(len[2] > len[imax]) imax = 2;
00309     
00310   Vec3f& u = bv.obb.axis[0];
00311   Vec3f& v = bv.obb.axis[1];
00312   Vec3f& w = bv.obb.axis[2];
00313     
00314   w = e[0].cross(e[1]);
00315   w.normalize();
00316   u = e[imax];
00317   u.normalize();
00318   v = w.cross(u);
00319 
00320   getExtentAndCenter(ps, NULL, NULL, NULL, 3, bv.obb.axis, bv.obb.To, bv.obb.extent);
00321 
00322   // compute radius and center
00323   FCL_REAL r0;
00324   Vec3f center;
00325   circumCircleComputation(p1, p2, p3, center, r0);
00326 
00327   bv.spheres[0].o = center;
00328   bv.spheres[0].r = r0;
00329 
00330   FCL_REAL r1 = r0 * invSinA;
00331   Vec3f delta = bv.obb.axis[2] * (r1 * cosA);
00332   
00333   bv.spheres[1].r = r1;
00334   bv.spheres[1].o = center - delta;
00335   bv.spheres[2].r = r1;
00336   bv.spheres[2].o = center + delta;
00337 }
00338 
00339 void fitn(Vec3f* ps, int n, kIOS& bv)
00340 {
00341   Matrix3f M;
00342   Vec3f E[3];
00343   Matrix3f::U s[3] = {0, 0, 0}; // three eigen values;
00344 
00345   getCovariance(ps, NULL, NULL, NULL, n, M);
00346   eigen(M, s, E);
00347   
00348   Vec3f* axis = bv.obb.axis;
00349   axisFromEigen(E, s, axis);
00350 
00351   getExtentAndCenter(ps, NULL, NULL, NULL, n, axis, bv.obb.To, bv.obb.extent);
00352 
00353   // get center and extension
00354   const Vec3f& center = bv.obb.To;
00355   const Vec3f& extent = bv.obb.extent;
00356   FCL_REAL r0 = maximumDistance(ps, NULL, NULL, NULL, n, center);
00357   
00358   // decide the k in kIOS
00359   if(extent[0] > kIOS_RATIO * extent[2])
00360   {
00361     if(extent[0] > kIOS_RATIO * extent[1]) bv.num_spheres = 5;
00362     else bv.num_spheres = 3;
00363   }
00364   else bv.num_spheres = 1;
00365 
00366   
00367   bv.spheres[0].o = center;
00368   bv.spheres[0].r = r0;
00369 
00370   if(bv.num_spheres >= 3)
00371   {
00372     FCL_REAL r10 = sqrt(r0 * r0 - extent[2] * extent[2]) * invSinA;
00373     Vec3f delta = axis[2] * (r10 * cosA - extent[2]);
00374     bv.spheres[1].o = center - delta;
00375     bv.spheres[2].o = center + delta;
00376    
00377     FCL_REAL r11 = 0, r12 = 0;
00378     r11 = maximumDistance(ps, NULL, NULL, NULL, n, bv.spheres[1].o);
00379     r12 = maximumDistance(ps, NULL, NULL, NULL, n, bv.spheres[2].o);
00380     bv.spheres[1].o += axis[2] * (-r10 + r11);
00381     bv.spheres[2].o += axis[2] * (r10 - r12);
00382 
00383     bv.spheres[1].r = r10;
00384     bv.spheres[2].r = r10;
00385   }
00386 
00387   if(bv.num_spheres >= 5)
00388   {
00389     FCL_REAL r10 = bv.spheres[1].r;
00390     Vec3f delta = axis[1] * (sqrt(r10 * r10 - extent[0] * extent[0] - extent[2] * extent[2]) - extent[1]);
00391     bv.spheres[3].o = bv.spheres[0].o - delta;
00392     bv.spheres[4].o = bv.spheres[0].o + delta;
00393     
00394     FCL_REAL r21 = 0, r22 = 0;
00395     r21 = maximumDistance(ps, NULL, NULL, NULL, n, bv.spheres[3].o);
00396     r22 = maximumDistance(ps, NULL, NULL, NULL, n, bv.spheres[4].o);
00397 
00398     bv.spheres[3].o += axis[1] * (-r10 + r21);
00399     bv.spheres[4].o += axis[1] * (r10 - r22);
00400     
00401     bv.spheres[3].r = r10;
00402     bv.spheres[4].r = r10;
00403   }
00404 }
00405 
00406 }
00407 
00408 namespace OBBRSS_fit_functions
00409 {
00410 void fit1(Vec3f* ps, OBBRSS& bv)
00411 {
00412   OBB_fit_functions::fit1(ps, bv.obb);
00413   RSS_fit_functions::fit1(ps, bv.rss);
00414 }
00415 
00416 void fit2(Vec3f* ps, OBBRSS& bv)
00417 {
00418   OBB_fit_functions::fit2(ps, bv.obb);
00419   RSS_fit_functions::fit2(ps, bv.rss);
00420 }
00421 
00422 void fit3(Vec3f* ps, OBBRSS& bv)
00423 {
00424   OBB_fit_functions::fit3(ps, bv.obb);
00425   RSS_fit_functions::fit3(ps, bv.rss);
00426 }
00427 
00428 void fitn(Vec3f* ps, int n, OBBRSS& bv)
00429 {
00430   OBB_fit_functions::fitn(ps, n, bv.obb);
00431   RSS_fit_functions::fitn(ps, n, bv.rss);
00432 }
00433 
00434 }
00435 
00436 
00437 
00438 template<>
00439 void fit(Vec3f* ps, int n, OBB& bv)
00440 {
00441   switch(n)
00442   {
00443   case 1:
00444     OBB_fit_functions::fit1(ps, bv);
00445     break;
00446   case 2:
00447     OBB_fit_functions::fit2(ps, bv);
00448     break;
00449   case 3:
00450     OBB_fit_functions::fit3(ps, bv);
00451     break;
00452   case 6:
00453     OBB_fit_functions::fit6(ps, bv);
00454     break;
00455   default:
00456     OBB_fit_functions::fitn(ps, n, bv);
00457   }
00458 }
00459 
00460 
00461 template<>
00462 void fit(Vec3f* ps, int n, RSS& bv)
00463 {
00464   switch(n)
00465   {
00466   case 1:
00467     RSS_fit_functions::fit1(ps, bv);
00468     break;
00469   case 2:
00470     RSS_fit_functions::fit2(ps, bv);
00471     break;
00472   case 3:
00473     RSS_fit_functions::fit3(ps, bv);
00474     break;
00475   default:
00476     RSS_fit_functions::fitn(ps, n, bv);
00477   }
00478 }
00479 
00480 template<>
00481 void fit(Vec3f* ps, int n, kIOS& bv)
00482 {
00483   switch(n)
00484   {
00485   case 1:
00486     kIOS_fit_functions::fit1(ps, bv);
00487     break;
00488   case 2:
00489     kIOS_fit_functions::fit2(ps, bv);
00490     break;
00491   case 3:
00492     kIOS_fit_functions::fit3(ps, bv);
00493     break;
00494   default:
00495     kIOS_fit_functions::fitn(ps, n, bv);
00496   }
00497 }
00498 
00499 template<>
00500 void fit(Vec3f* ps, int n, OBBRSS& bv)
00501 {
00502   switch(n)
00503   {
00504   case 1:
00505     OBBRSS_fit_functions::fit1(ps, bv);
00506     break;
00507   case 2:
00508     OBBRSS_fit_functions::fit2(ps, bv);
00509     break;
00510   case 3:
00511     OBBRSS_fit_functions::fit3(ps, bv);
00512     break;
00513   default:
00514     OBBRSS_fit_functions::fitn(ps, n, bv);
00515   }
00516 }
00517 
00518 
00519 OBB BVFitter<OBB>::fit(unsigned int* primitive_indices, int num_primitives)
00520 {
00521   OBB bv;
00522 
00523   Matrix3f M; // row first matrix
00524   Vec3f E[3]; // row first eigen-vectors
00525   Matrix3f::U s[3]; // three eigen values
00526 
00527   getCovariance(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, M);
00528   eigen(M, s, E);
00529 
00530   axisFromEigen(E, s, bv.axis);
00531 
00532   // set obb centers and extensions
00533   getExtentAndCenter(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, bv.axis, bv.To, bv.extent);
00534 
00535   return bv;
00536 }
00537 
00538 OBBRSS BVFitter<OBBRSS>::fit(unsigned int* primitive_indices, int num_primitives)
00539 {
00540   OBBRSS bv;
00541   Matrix3f M;
00542   Vec3f E[3];
00543   Matrix3f::U s[3];
00544 
00545   getCovariance(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, M);
00546   eigen(M, s, E);
00547 
00548   axisFromEigen(E, s, bv.obb.axis);
00549   bv.rss.axis[0] = bv.obb.axis[0];
00550   bv.rss.axis[1] = bv.obb.axis[1];
00551   bv.rss.axis[2] = bv.obb.axis[2];
00552 
00553   getExtentAndCenter(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, bv.obb.axis, bv.obb.To, bv.obb.extent);
00554 
00555   Vec3f origin;
00556   FCL_REAL l[2];
00557   FCL_REAL r;
00558   getRadiusAndOriginAndRectangleSize(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, bv.rss.axis, origin, l, r);
00559 
00560   bv.rss.Tr = origin;
00561   bv.rss.l[0] = l[0];
00562   bv.rss.l[1] = l[1];
00563   bv.rss.r = r;
00564 
00565   return bv;
00566 }
00567 
00568 RSS BVFitter<RSS>::fit(unsigned int* primitive_indices, int num_primitives)
00569 {
00570   RSS bv;
00571 
00572   Matrix3f M; // row first matrix
00573   Vec3f E[3]; // row first eigen-vectors
00574   Matrix3f::U s[3]; // three eigen values
00575   getCovariance(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, M);
00576   eigen(M, s, E);
00577   axisFromEigen(E, s, bv.axis);
00578 
00579   // set rss origin, rectangle size and radius
00580 
00581   Vec3f origin;
00582   FCL_REAL l[2];
00583   FCL_REAL r;
00584   getRadiusAndOriginAndRectangleSize(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, bv.axis, origin, l, r);
00585 
00586   bv.Tr = origin;
00587   bv.l[0] = l[0];
00588   bv.l[1] = l[1];
00589   bv.r = r;
00590 
00591 
00592   return bv;
00593 }
00594 
00595 
00596 kIOS BVFitter<kIOS>::fit(unsigned int* primitive_indices, int num_primitives)
00597 {
00598   kIOS bv;
00599 
00600   Matrix3f M; // row first matrix
00601   Vec3f E[3]; // row first eigen-vectors
00602   Matrix3f::U s[3];
00603   
00604   getCovariance(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, M);
00605   eigen(M, s, E);
00606 
00607   Vec3f* axis = bv.obb.axis;
00608   axisFromEigen(E, s, axis);
00609 
00610   // get centers and extensions
00611   getExtentAndCenter(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, axis, bv.obb.To, bv.obb.extent);
00612 
00613   const Vec3f& center = bv.obb.To;
00614   const Vec3f& extent = bv.obb.extent;
00615   FCL_REAL r0 = maximumDistance(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, center);
00616 
00617   // decide k in kIOS
00618   if(extent[0] > kIOS_RATIO * extent[2])
00619   {
00620     if(extent[0] > kIOS_RATIO * extent[1]) bv.num_spheres = 5;
00621     else bv.num_spheres = 3;
00622   }
00623   else bv.num_spheres = 1;
00624 
00625   bv.spheres[0].o = center;
00626   bv.spheres[0].r = r0;
00627 
00628   if(bv.num_spheres >= 3)
00629   {
00630     FCL_REAL r10 = sqrt(r0 * r0 - extent[2] * extent[2]) * invSinA;
00631     Vec3f delta = axis[2] * (r10 * cosA - extent[2]);
00632     bv.spheres[1].o = center - delta;
00633     bv.spheres[2].o = center + delta;
00634 
00635     FCL_REAL r11 = maximumDistance(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, bv.spheres[1].o);
00636     FCL_REAL r12 = maximumDistance(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, bv.spheres[2].o);
00637 
00638     bv.spheres[1].o += axis[2] * (-r10 + r11);
00639     bv.spheres[2].o += axis[2] * (r10 - r12);
00640 
00641     bv.spheres[1].r = r10;
00642     bv.spheres[2].r = r10;
00643   }
00644 
00645   if(bv.num_spheres >= 5)
00646   {
00647     FCL_REAL r10 = bv.spheres[1].r;
00648     Vec3f delta = axis[1] * (sqrt(r10 * r10 - extent[0] * extent[0] - extent[2] * extent[2]) - extent[1]);
00649     bv.spheres[3].o = bv.spheres[0].o - delta;
00650     bv.spheres[4].o = bv.spheres[0].o + delta;
00651     
00652     FCL_REAL r21 = 0, r22 = 0;
00653     r21 = maximumDistance(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, bv.spheres[3].o);
00654     r22 = maximumDistance(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, bv.spheres[4].o);
00655 
00656     bv.spheres[3].o += axis[1] * (-r10 + r21);
00657     bv.spheres[4].o += axis[1] * (r10 - r22);
00658     
00659     bv.spheres[3].r = r10;
00660     bv.spheres[4].r = r10;
00661   }
00662 
00663   return bv;
00664 }
00665 
00666 
00667 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


fcl
Author(s): Jia Pan
autogenerated on Tue Jan 15 2013 16:05:30