• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

Containment.h

Go to the documentation of this file.
00001 // GMTL is (C) Copyright 2001-2010 by Allen Bierbaum
00002 // Distributed under the GNU Lesser General Public License 2.1 with an
00003 // addendum covering inlined code. (See accompanying files LICENSE and
00004 // LICENSE.addendum or http://www.gnu.org/copyleft/lesser.txt)
00005 
00006 #ifndef _GMTL_CONTAINMENT_H_
00007 #define _GMTL_CONTAINMENT_H_
00008 
00009 // new stuff
00010 #include <vector>
00011 #include <gmtl/Sphere.h>
00012 #include <gmtl/AABox.h>
00013 #include <gmtl/Frustum.h>
00014 #include <gmtl/Tri.h>
00015 #include <gmtl/VecOps.h>
00016 
00017 // old stuff
00018 //#include <gmtl/OOBox.h>
00019 //#include <gmtl/AABox.h>
00020 //#include <gmtl/Fit/GaussPointsFit.h>
00021 //#include <gmtl/matVecFuncs.h>
00022 //#include <gmtl/Quat.h>
00023 
00024 namespace gmtl
00025 {
00026 
00027 //-----------------------------------------------------------------------------
00028 // Sphere
00029 //-----------------------------------------------------------------------------
00030 
00040 template< class DATA_TYPE >
00041 bool isInVolume( const Sphere<DATA_TYPE>& container,
00042                  const Point<DATA_TYPE, 3>& pt )
00043 {
00044    // The point is inside the sphere if the vector computed from the center of
00045    // the sphere to the point has a magnitude less than or equal to the radius
00046    // of the sphere.
00047    // |pt - center| <= radius
00048    return ( length(gmtl::Vec<DATA_TYPE,3>(pt - container.mCenter)) <= container.mRadius );
00049 }
00050 
00060 template< class DATA_TYPE >
00061 bool isInVolume( const Sphere<DATA_TYPE>& container,
00062                  const Sphere<DATA_TYPE>& sphere )
00063 {
00064    // the sphere is inside container if the distance between the centers of the
00065    // spheres plus the radius of the inner sphere is less than or equal to the
00066    // radius of the containing sphere.
00067    // |sphere.center - container.center| + sphere.radius <= container.radius
00068    return ( length(gmtl::Vec<DATA_TYPE,3>(sphere.mCenter - container.mCenter)) + sphere.mRadius
00069             <= container.mRadius );
00070 }
00071 
00078 template< class DATA_TYPE >
00079 void extendVolume( Sphere<DATA_TYPE>& container,
00080                    const Point<DATA_TYPE, 3>& pt )
00081 {
00082    // check if we already contain the point
00083    if ( isInVolume( container, pt ) )
00084    {
00085       return;
00086    }
00087 
00088    // make a vector pointing from the center of the sphere to pt. this is the
00089    // direction in which we need to move the sphere's center
00090    Vec<DATA_TYPE, 3> dir = pt - container.mCenter;
00091    DATA_TYPE len = normalize( dir );
00092 
00093    // compute what the new radius should be
00094    DATA_TYPE newRadius = (len + container.mRadius) * static_cast<DATA_TYPE>(0.5);
00095 
00096    // compute the new center for the sphere
00097    Point<DATA_TYPE, 3> newCenter = container.mCenter +
00098                                    (dir * (newRadius - container.mRadius));
00099 
00100    // modify container to its new values
00101    container.mCenter = newCenter;
00102    container.mRadius = newRadius;
00103 }
00104 
00111 template< class DATA_TYPE >
00112 void extendVolume( Sphere<DATA_TYPE>& container,
00113                    const Sphere<DATA_TYPE>& sphere )
00114 {
00115    // check if we already contain the sphere
00116    if ( isInVolume( container, sphere ) )
00117    {
00118       return;
00119    }
00120 
00121    // make a vector pointing from the center of container to sphere. this is the
00122    // direction in which we need to move container's center
00123    Vec<DATA_TYPE, 3> dir = sphere.mCenter - container.mCenter;
00124    DATA_TYPE len = normalize( dir );
00125 
00126    // compute what the new radius should be
00127    DATA_TYPE newRadius = (len + sphere.mRadius + container.mRadius) *
00128                          static_cast<DATA_TYPE>(0.5);
00129 
00130    // compute the new center for container
00131    Point<DATA_TYPE, 3> newCenter = container.mCenter +
00132                                    (dir * (newRadius - container.mRadius));
00133 
00134    // modify container to its new values
00135    container.mCenter = newCenter;
00136    container.mRadius = newRadius;
00137 }
00138 
00149 template< class DATA_TYPE >
00150 void makeVolume( Sphere<DATA_TYPE>& container,
00151                  const std::vector< Point<DATA_TYPE, 3> >& pts )
00152 {
00153    gmtlASSERT( pts.size() > 0  && "pts must contain at least 1 point" );
00154 
00155    // Implementation based on the Sphere Centered at Average of Points algorithm
00156    // found in "3D Game Engine Design" by Devud G, Eberly (pg. 27)
00157    typename std::vector< Point<DATA_TYPE, 3> >::const_iterator itr = pts.begin();
00158 
00159    // compute the average of the points as the center
00160    Point<DATA_TYPE, 3> sum = *itr;
00161    ++itr;
00162    while ( itr != pts.end() )
00163    {
00164       sum += *itr;
00165       ++itr;
00166    }
00167    container.mCenter = sum / static_cast<DATA_TYPE>(pts.size());
00168 
00169    // compute the distance from the computed center to point furthest from that
00170    // center as the radius
00171    DATA_TYPE radiusSqr(0);
00172    for ( itr = pts.begin(); itr != pts.end(); ++itr )
00173    {
00174       DATA_TYPE len = lengthSquared( gmtl::Vec<DATA_TYPE,3>( (*itr) - container.mCenter) );
00175       if ( len > radiusSqr )
00176          radiusSqr = len;
00177    }
00178 
00179    container.mRadius = Math::sqrt( radiusSqr );
00180 }
00181 
00182 /*
00183 template< class DATA_TYPE >
00184 void makeVolume( Sphere<DATA_TYPE>& container,
00185                  const std::vector< Point<DATA_TYPE, 3> >& pts )
00186 {
00187    gmtlASSERT( pts.size() > 1  && "pts must contain at least 2 points" );
00188 
00189    // make a sphere around the first 2 points and then extend the sphere by each
00190    // point thereafter. we could probably be smarter about this ...
00191    std::vector< Point<DATA_TYPE, 3> >::const_iterator itr = pts.begin();
00192 
00193    // make the initial sphere
00194    const Point<DATA_TYPE, 3>& first = *itr;
00195    ++itr;
00196    const Point<DATA_TYPE, 3>& second = *itr;
00197    ++itr;
00198    const Vec<DATA_TYPE, 3> dir = second - first;
00199    container.mRadius = length(dir) * static_cast<DATA_TYPE>(0.5);
00200    container.mCenter = first + (dir * container.mRadius);
00201 
00202    // iterate through the remaining points and extend the container to fit each
00203    // point. yay code reuse!
00204    while ( itr != pts.end() )
00205    {
00206       extendVolume( container, *itr );
00207       ++itr;
00208    }
00209 }
00210 */
00221 /*
00222 template< class DATA_TYPE >
00223 void makeVolume( Sphere<DATA_TYPE>& container,
00224                  const std::vector< Sphere<DATA_TYPE> >& spheres )
00225 {
00226    gmtlASSERT( spheres.size() > 1  && "spheres must contain at least 2 points" );
00227 
00228    // make a sphere around the first 2 points and then extend the sphere by each
00229    // point thereafter. we could probably be smarter about this ...
00230    std::vector< Sphere<DATA_TYPE> >::const_iterator itr = spheres.begin();
00231 
00232    // make the initial sphere
00233    const Sphere<DATA_TYPE>& first = *itr;
00234    ++itr;
00235    const Sphere<DATA_TYPE>& second = *itr;
00236    ++itr;
00237    const Vec<DATA_TYPE, 3> dir = second.mCenter - first.mCenter;
00238    container.mRadius = (length(dir) + first.mRadius + second.mRadius) *
00239                        static_cast<DATA_TYPE>(0.5);
00240    container.mCenter = first.mCenter +
00241                        (dir * (container.mRadius - first.mRadius));
00242 
00243    // iterate through the remaining points and extend the container to fit each
00244    // point. yay code reuse!
00245    while ( itr != spheres.end() )
00246    {
00247       extendVolume( container, *itr );
00248       ++itr;
00249    }
00250 }
00251 */
00261 template< class DATA_TYPE >
00262 bool isOnVolume( const Sphere<DATA_TYPE>& container,
00263                  const Point<DATA_TYPE, 3>& pt )
00264 {
00265    // |center - pt| - radius == 0
00266    return ( length(gmtl::Vec<DATA_TYPE,3>(container.mCenter - pt)) - container.mRadius == 0 );
00267 }
00268 
00279 template< class DATA_TYPE >
00280 bool isOnVolume( const Sphere<DATA_TYPE>& container,
00281                  const Point<DATA_TYPE, 3>& pt,
00282                  const DATA_TYPE& tol )
00283 {
00284    gmtlASSERT( tol >= 0 && "tolerance must be positive" );
00285 
00286    // abs( |center-pt| - radius ) < tol
00287    return ( Math::abs( length( gmtl::Vec<DATA_TYPE,3>(container.mCenter - pt)) - container.mRadius )
00288             <= tol );
00289 }
00290 
00291 //-----------------------------------------------------------------------------
00292 // AABox
00293 //-----------------------------------------------------------------------------
00294 
00304 template< class DATA_TYPE>
00305 bool isInVolume(const AABox<DATA_TYPE>& container,
00306                 const Point<DATA_TYPE, 3>& pt)
00307 {
00308    if (! container.isEmpty())
00309    {
00310       return ( pt[0] >= container.mMin[0] &&
00311                pt[1] >= container.mMin[1] &&
00312                pt[2] >= container.mMin[2] &&
00313                pt[0] <= container.mMax[0] &&
00314                pt[1] <= container.mMax[1] &&
00315                pt[2] <= container.mMax[2]);
00316    }
00317    else
00318    {
00319       return false;
00320    }
00321 }
00322 
00333 template< class DATA_TYPE>
00334 bool isInVolumeExclusive(const AABox<DATA_TYPE>& container,
00335                 const Point<DATA_TYPE, 3>& pt)
00336 {
00337    if (! container.isEmpty())
00338    {
00339       return ( pt[0] > container.mMin[0] &&
00340                pt[1] > container.mMin[1] &&
00341                pt[2] > container.mMin[2] &&
00342                pt[0] < container.mMax[0] &&
00343                pt[1] < container.mMax[1] &&
00344                pt[2] < container.mMax[2]);
00345    }
00346    else
00347    {
00348       return false;
00349    }
00350 }
00351 
00352 
00353 
00354 
00364 template< class DATA_TYPE >
00365 bool isInVolume(const AABox<DATA_TYPE>& container,
00366                 const AABox<DATA_TYPE>& box)
00367 {
00368    // Empty boxes don't overlap
00369    if (container.isEmpty() || box.isEmpty())
00370    {
00371       return false;
00372    }
00373  
00374    if (container.mMin[0] <= box.mMin[0] && container.mMax[0] >= box.mMax[0] &&
00375        container.mMin[1] <= box.mMin[1] && container.mMax[1] >= box.mMax[1] &&
00376        container.mMin[2] <= box.mMin[2] && container.mMax[2] >= box.mMax[2])
00377    {
00378       return true;
00379    }
00380    else
00381    {
00382       return false;
00383    }
00384 }
00385 
00392 template< class DATA_TYPE >
00393 void extendVolume(AABox<DATA_TYPE>& container,
00394                   const Point<DATA_TYPE, 3>& pt)
00395 {
00396    if (! container.isEmpty())
00397    {
00398       // X coord
00399       if (pt[0] > container.mMax[0])
00400       {
00401          container.mMax[0] = pt[0];
00402       }
00403       else if (pt[0] < container.mMin[0])
00404       {
00405          container.mMin[0] = pt[0];
00406       }
00407 
00408       // Y coord
00409       if (pt[1] > container.mMax[1])
00410       {
00411          container.mMax[1] = pt[1];
00412       }
00413       else if (pt[1] < container.mMin[1])
00414       {
00415          container.mMin[1] = pt[1];
00416       }
00417 
00418       // Z coord
00419       if (pt[2] > container.mMax[2])
00420       {
00421          container.mMax[2] = pt[2];
00422       }
00423       else if (pt[2] < container.mMin[2])
00424       {
00425          container.mMin[2] = pt[2];
00426       }
00427    }
00428    else
00429    {
00430       // Make a box with essentially zero volume at the point
00431       container.setMin(pt);
00432       container.setMax(pt);
00433       container.setEmpty(false);
00434    }
00435 }
00436 
00443 template< class DATA_TYPE >
00444 void extendVolume(AABox<DATA_TYPE>& container,
00445                   const AABox<DATA_TYPE>& box)
00446 {
00447    // Can't extend by an empty box
00448    if (box.isEmpty())
00449    {
00450       return;
00451    }
00452 
00453    // An empty container is extended to be the box
00454    if (container.isEmpty())
00455    {
00456       container = box;
00457    }
00458 
00459    // Just extend by the corners of the box
00460    extendVolume(container, box.getMin());
00461    extendVolume(container, box.getMax());
00462 }
00463 
00469 template< class DATA_TYPE >
00470 void makeVolume(AABox<DATA_TYPE>& box, const Sphere<DATA_TYPE>& sph)
00471 {
00472    const gmtl::Point<DATA_TYPE, 3>& center = sph.getCenter();
00473    const DATA_TYPE& radius = sph.getRadius();
00474 
00475    // Calculate the min and max points for the box
00476    gmtl::Point<DATA_TYPE, 3> min_pt(center[0] - radius,
00477                                     center[1] - radius,
00478                                     center[2] - radius);
00479    gmtl::Point<DATA_TYPE, 3> max_pt(center[0] + radius,
00480                                     center[1] + radius,
00481                                     center[2] + radius);
00482 
00483    box.setMin(min_pt);
00484    box.setMax(max_pt);
00485    box.setEmpty(radius == DATA_TYPE(0));
00486 }
00487 
00488 //-----------------------------------------------------------------------------
00489 // Frustum
00490 //-----------------------------------------------------------------------------
00491 
00492 const unsigned int IN_FRONT_OF_ALL_PLANES = 6;
00493 
00494 template<typename T>
00495 inline bool isInVolume(const Frustum<T>& f, const Point<T, 3>& p,
00496                        unsigned int& idx /*out*/)
00497 {
00498    for ( unsigned int i = 0; i < 6; ++i )
00499    {
00500       T dist = dot(f.mPlanes[i].mNorm, static_cast< Vec<T, 3> >(p)) + f.mPlanes[i].mOffset;
00501       if (dist < T(0.0) )
00502       {
00503          idx = i;
00504          return false;
00505       }
00506    }
00507      
00508    idx = IN_FRONT_OF_ALL_PLANES;
00509    return true;
00510 }
00511 
00512 template<typename T>
00513 inline bool isInVolume(const Frustum<T>& f, const Sphere<T>& s)
00514 {
00515    for ( unsigned int i = 0; i < 6; ++i )
00516    {
00517       T dist = dot(f.mPlanes[i].mNorm, static_cast< Vec<T, 3> >(s.getCenter())) + f.mPlanes[i].mOffset;
00518       if ( dist <= -T(s.getRadius()) )
00519       {
00520          return false;
00521       }
00522    }
00523 
00524    return true;
00525 }
00526 
00527 template<typename T>
00528 inline bool isInVolume(const Frustum<T>& f, const AABox<T>& box)
00529 {
00530    const Point<T, 3>& min = box.getMin();
00531    const Point<T, 3>& max = box.getMax();
00532    Point<T, 3> p[8];
00533    p[0] = min;
00534    p[1] = max;
00535    p[2] = Point<T, 3>(max[0], min[1], min[2]);
00536    p[3] = Point<T, 3>(min[0], max[1], min[2]);
00537    p[4] = Point<T, 3>(min[0], min[1], max[2]);
00538    p[5] = Point<T, 3>(max[0], max[1], min[2]);
00539    p[6] = Point<T, 3>(min[0], max[1], max[2]);
00540    p[7] = Point<T, 3>(max[0], min[1], max[2]);
00541 
00542    unsigned int idx = 6;
00543 
00544    if ( isInVolume(f, p[0], idx) )
00545    {
00546       return true;
00547    }
00548 
00549    // now we have the index of the seperating plane int idx, so check if all
00550    // other points lie on the backside of this plane too
00551 
00552    for ( unsigned int i = 1; i < 8; ++i )
00553    {
00554       T dist = dot(f.mPlanes[idx].mNorm, static_cast< Vec<T, 3> >(p[i])) + f.mPlanes[idx].mOffset;      
00555       if ( dist > T(0.0) )
00556       {
00557          return true;
00558       }
00559    }
00560       
00561    return false;
00562 }
00563 
00564 template<typename T>
00565 inline bool isInVolume(const Frustum<T>& f, const Tri<T>& tri)
00566 {
00567    unsigned int junk;
00568 
00569    if ( isInVolume(f, tri[0], junk) )
00570    {
00571       return true;
00572    }
00573 
00574    if ( isInVolume(f, tri[1], junk) )
00575    {
00576       return true;
00577    }
00578 
00579    if ( isInVolume(f, tri[2], junk) )
00580    {
00581       return true;
00582    }
00583 
00584    return false;
00585 }
00586 
00587 /*
00588 //------------------------------------------------------------------------------
00589 // Begin old GMTL code
00590 //------------------------------------------------------------------------------
00591 inline void computeContainment( AABox& box, const std::vector<gmtl::Point3>& points,
00592                          Point3& minPt, Point3& maxPt )
00593 //void MgcContAlignedBox (int iQuantity, const MgcVector3* akPoint,
00594 //    MgcVector3& rkMin, MgcVector3& rkMax)
00595 {
00596    if (points.empty())
00597       return;
00598 
00599    minPt = points[0];
00600    maxPt = minPt;
00601 
00602    for (unsigned i = 1; i < points.size(); i++)
00603    {
00604       if ( points[i][Xelt] < minPt[Xelt] )
00605          minPt[Xelt] = points[i][Xelt];
00606       else if ( points[i][Xelt] > maxPt[Xelt] )
00607          maxPt[Xelt] = points[i][Xelt];
00608 
00609       if ( points[i][Yelt] < minPt[Yelt] )
00610          minPt[Yelt] = points[i][Yelt];
00611       else if ( points[i][Yelt] > maxPt[Yelt] )
00612          maxPt[Yelt] = points[i][Yelt];
00613 
00614       if ( points[i][Zelt] < minPt[Zelt] )
00615          minPt[Zelt] = points[i][Zelt];
00616       else if ( points[i][Zelt] > maxPt[Zelt] )
00617          maxPt[Zelt] = points[i][Zelt];
00618    }
00619 
00620    // Now update the box
00621    box.makeEmpty();
00622    box.mMax = maxPt;
00623    box.mMin = minPt;
00624 }
00625 //----------------------------------------------------------------------------
00626 //----------------------------------------------------------------------------
00627 //MgcBox3 MgcContOrientedBox (int iQuantity, const MgcVector3* akPoint)
00628 inline void computeContainment( OOBox& box, const std::vector<gmtl::Point3>& points)
00629 {
00630     //MgcGaussPointsFit(iQuantity,akPoint,kBox.Center(),kBox.Axes(),
00631     //    kBox.Extents());
00632 
00633     gmtl::GaussPointsFit(points.size(), &points[0], box.center(), box.axes(), box.halfLens());
00634 
00635     // Let C be the box center and let U0, U1, and U2 be the box axes.  Each
00636     // input point is of the form X = C + y0*U0 + y1*U1 + y2*U2.  The
00637     // following code computes min(y0), max(y0), min(y1), max(y1), min(y2),
00638     // and max(y2).  The box center is then adjusted to be
00639     //   C' = C + 0.5*(min(y0)+max(y0))*U0 + 0.5*(min(y1)+max(y1))*U1 +
00640     //        0.5*(min(y2)+max(y2))*U2
00641 #ifdef _DEBUG
00642    gmtl::OOBox box_test;
00643    box_test = box;
00644    gmtl::Vec3 ax0 = box_test.axis(0);
00645    gmtl::Vec3 ax1 = box_test.axis(1);
00646    gmtl::Vec3 ax2 = box_test.axis(2);
00647 #endif
00648 
00649     gmtlASSERT(box.axis(0).isNormalized());
00650     gmtlASSERT(box.axis(1).isNormalized());
00651     gmtlASSERT(box.axis(2).isNormalized());
00652 
00653     // XXX: Sign is sometimes wrong here
00654     // This is hack code to make it "work right"
00655     Vec3 cross;
00656     cross = box.axis(0).cross(box.axis(1));
00657     cross.normalize();
00658     box.axis(2) = cross;
00659 
00660     Vec3 kDiff = points[0] - box.center();
00661     float fY0Min = kDiff.dot(box.axis(0)), fY0Max = fY0Min;
00662     float fY1Min = kDiff.dot(box.axis(1)), fY1Max = fY1Min;
00663     float fY2Min = kDiff.dot(box.axis(2)), fY2Max = fY2Min;
00664 
00665     float fY0, fY1, fY2;
00666 
00667     for (unsigned i = 1; i < points.size(); i++)
00668     {
00669         kDiff = points[i] - box.center();
00670 
00671         fY0 = kDiff.dot(box.axis(0));
00672         if ( fY0 < fY0Min )
00673             fY0Min = fY0;
00674         else if ( fY0 > fY0Max )
00675             fY0Max = fY0;
00676 
00677         fY1 = kDiff.dot(box.axis(1));
00678         if ( fY1 < fY1Min )
00679             fY1Min = fY1;
00680         else if ( fY1 > fY1Max )
00681             fY1Max = fY1;
00682 
00683         fY2 = kDiff.dot(box.axis(2));
00684         if ( fY2 < fY2Min )
00685             fY2Min = fY2;
00686         else if ( fY2 > fY2Max )
00687             fY2Max = fY2;
00688     }
00689 
00690     box.center() += (0.5*(fY0Min+fY0Max))*box.axis(0) +
00691                     (0.5*(fY1Min+fY1Max))*box.axis(1) +
00692                     (0.5*(fY2Min+fY2Max))*box.axis(2);
00693 
00694     box.halfLen(0) = 0.5*(fY0Max - fY0Min);
00695     box.halfLen(1) = 0.5*(fY1Max - fY1Min);
00696     box.halfLen(2) = 0.5*(fY2Max - fY2Min);
00697 }
00698 
00699 */
00700 /*
00701 inline void computeContainment (OOBox& out_box, const OOBox& box0, const OOBox& box1, bool fast=true)
00702 {
00703    gmtl::OOBox ret_box;    // The resulting box
00704 
00705    if (fast)
00706    {
00707       ret_box.center() = 0.5*(box0.center() + box1.center());       // Center at average
00708 
00709       // Average the quats to get a new orientation
00710       Quat quat0, quat1;
00711       quat0.makeAxes(box0.axis(0), box0.axis(1), box0.axis(2));
00712       quat1.makeAxes(box1.axis(0), box1.axis(1), box1.axis(2));
00713       if ( quat0.dot(quat1) < 0.0 )
00714          quat1 = -quat1;
00715 
00716       Quat full_quat = quat0 + quat1;
00717 
00718       //float inv_len = 1.0/Math::sqrt(full_quat.norm());
00719       //full_quat = inv_len*full_quat;
00720       full_quat.normalize();
00721       full_quat.getAxes(ret_box.axis(0), ret_box.axis(1), ret_box.axis(2));
00722 
00723       // Now that we have new orientation, extend half lens to cover the volume
00724       //
00725       unsigned i, j;
00726       Point3 verts[8];
00727       Vec3 diff;
00728       float aDot;
00729 
00730       ret_box.halfLen(0) = 0.0;
00731       ret_box.halfLen(1) = 0.0;
00732       ret_box.halfLen(2) = 0.0;
00733 
00734       box0.getVerts(verts);
00735       for (i = 0; i < 8; i++)
00736       {
00737          diff = verts[i] - ret_box.center();
00738          for (j = 0; j < 3; j++)                       // For each axis of box0
00739          {
00740             aDot = Math::abs(diff.dot(ret_box.axis(j)));
00741             if ( aDot > ret_box.halfLen(j) )
00742                ret_box.halfLen(j) = aDot;
00743          }
00744       }
00745 
00746       box1.getVerts(verts);
00747       for (i = 0; i < 8; i++)
00748       {
00749          diff = verts[i] - ret_box.center();
00750          for (j = 0; j < 3; j++)
00751          {
00752             aDot = Math::abs(diff.dot(ret_box.axis(j)));
00753             if ( aDot > ret_box.halfLen(j) )
00754                ret_box.halfLen(j) = aDot;
00755          }
00756       }
00757    }
00758    else     // Tighter fit
00759    {
00760       // Hack that will do it correctly, but is slow
00761       Point3 verts[8];
00762       std::vector<gmtl::Point3> vert_points;
00763 
00764       box0.getVerts(verts);
00765       for (unsigned i=0;i<8;i++) vert_points.push_back(verts[i]);
00766       box1.getVerts(verts);
00767       for (unsigned i=0;i<8;i++) vert_points.push_back(verts[i]);
00768 
00769       computeContainment(ret_box, vert_points);
00770    }
00771 
00772    out_box = ret_box;
00773 }
00774 */
00775 
00776 
00777 }
00778 
00779 #endif

Generated on Sun Sep 19 2010 14:35:14 for GenericMathTemplateLibrary by  doxygen 1.7.1