ContinuousTriangleIntersection.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
00024 ******************************************************************************/
00025 #include <sofa/component/collision/ContinuousTriangleIntersection.h>
00026 #include <sofa/helper/rmath.h>
00027 
00028 namespace sofa
00029 {
00030 
00031 namespace component
00032 {
00033 
00034 namespace collision
00035 {
00036 
00037 bool ContinuousTriangleIntersection::isCollision(void)
00038 {
00039     SReal t[3], u[3], v[3];
00040     double dt = 0.01; //Scene::getInstance()->getDt();
00041     //std::cout<<"Triangle 2  : " << tr2 << std::endl;
00042 
00043 //  getc(stdin);
00044 
00045     if (intersectPointTriangle(t[0], u[0], v[0], tr2.p1(), tr2.v1(), tr1.p1(), tr1.v1(), tr1.p2(), tr1.v2(), tr1.p3(), tr1.v3(), dt))
00046     {
00047         // std::cout<<"Triangle 1  : " << tr1 << std::endl;
00048         return true;
00049     }
00050 
00051     if (intersectPointTriangle(t[1], u[1], v[1], tr2.p2(), tr2.v2(), tr1.p1(), tr1.v1(), tr1.p2(), tr1.v2(), tr1.p3(), tr1.v3(), dt))
00052     {
00053         // std::cout<<"Triangle 1  : " << tr1 << std::endl;
00054         return true;
00055     }
00056     
00057     if (intersectPointTriangle(t[2], u[2], v[2], tr2.p3(), tr2.v3(), tr1.p1(), tr1.v1(), tr1.p2(), tr1.v2(), tr1.p3(), tr1.v3(), dt))
00058     {
00059         // std::cout<<"Triangle 1  : " << tr1 << std::endl;
00060         return true;
00061     }
00062 
00063     if (intersectPointTriangle(t[0], u[0], v[0], tr1.p1(), tr1.v1(), tr2.p1(), tr2.v1(), tr2.p2(), tr2.v2(), tr2.p3(), tr2.v3(), dt))
00064     {
00065         // std::cout<<"Triangle 1  : " << tr1 << std::endl;
00066         return true;    
00067     }
00068 
00069     if (intersectPointTriangle(t[1], u[1], v[1], tr1.p2(), tr1.v2(), tr2.p1(), tr2.v1(), tr2.p2(), tr2.v2(), tr2.p3(), tr2.v3(), dt))
00070     {
00071         // std::cout<<"Triangle 1  : " << tr1 << std::endl; 
00072         return true;
00073     }
00074 
00075     if (intersectPointTriangle(t[2], u[2], v[2], tr1.p3(), tr1.v3(), tr2.p1(), tr2.v1(), tr2.p2(), tr2.v2(), tr2.p3(), tr2.v3(), dt))
00076     {
00077          //std::cout<<"Triangle 1  : " << tr1 << std::endl;
00078         return true;
00079     }
00080 
00081     if (intersectEdgeEdge(t[0], u[0], v[0], tr1.p1(), tr1.p2(), tr1.v1(), tr1.v2(), tr2.p1(), tr2.p2(), tr2.v1(), tr2.v2(), dt))
00082     {
00083         // std::cout<<"Triangle 1  : " << tr1 << std::endl;
00084         return true;
00085     }
00086 
00087     if (intersectEdgeEdge(t[1], u[1], v[1], tr1.p1(), tr1.p3(), tr1.v1(), tr1.v3(), tr2.p1(), tr2.p2(), tr2.v1(), tr2.v2(), dt))
00088     {
00089         // std::cout<<"Triangle 1  : " << tr1 << std::endl;
00090         return true;
00091     }
00092     
00093     if (intersectEdgeEdge(t[2], u[2], v[2], tr1.p2(), tr1.p3(), tr1.v2(), tr1.v3(), tr2.p1(), tr2.p2(), tr2.v1(), tr2.v2(), dt))
00094     {
00095         // std::cout<<"Triangle 1  : " << tr1 << std::endl;
00096         return true;
00097     }
00098 
00099     if (intersectEdgeEdge(t[0], u[0], v[0], tr1.p1(), tr1.p2(), tr1.v1(), tr1.v2(), tr2.p1(), tr2.p3(), tr2.v1(), tr2.v3(), dt))
00100     {
00101         // std::cout<<"Triangle 1  : " << tr1 << std::endl;
00102         return true;
00103     }
00104 
00105     if (intersectEdgeEdge(t[1], u[1], v[1], tr1.p1(), tr1.p3(), tr1.v1(), tr1.v3(), tr2.p1(), tr2.p3(), tr2.v1(), tr2.v3(), dt))
00106     {
00107         // std::cout<<"Triangle 1  : " << tr1 << std::endl;
00108         return true;
00109     }
00110 
00111     if (intersectEdgeEdge(t[2], u[2], v[2], tr1.p2(), tr1.p3(), tr1.v2(), tr1.v3(), tr2.p1(), tr2.p3(), tr2.v1(), tr2.v3(), dt))
00112     {
00113         //std::cout<<"Triangle 1  : " << tr1 << std::endl;
00114         return true;
00115     }
00116 
00117     if (intersectEdgeEdge(t[0], u[0], v[0], tr1.p1(), tr1.p2(), tr1.v1(), tr1.v2(), tr2.p2(), tr2.p3(), tr2.v2(), tr2.v3(), dt))
00118     {
00119         // std::cout<<"Triangle 1  : " << tr1 << std::endl;
00120         return true;
00121     }
00122 
00123     if (intersectEdgeEdge(t[1], u[1], v[1], tr1.p1(), tr1.p3(), tr1.v1(), tr1.v3(), tr2.p2(), tr2.p3(), tr2.v2(), tr2.v3(), dt))
00124     {
00125         // std::cout<<"Triangle 1  : " << tr1 << std::endl; 
00126         return true;
00127     }
00128 
00129     if (intersectEdgeEdge(t[2], u[2], v[2], tr1.p2(), tr1.p3(), tr1.v2(), tr1.v3(), tr2.p2(), tr2.p3(), tr2.v2(), tr2.v3(), dt))
00130     {
00131         // std::cout<<"Triangle 1  : " << tr1 << std::endl; 
00132         return true;
00133     }
00134 
00135     return false;
00136 
00137 }
00138 
00139 core::componentmodel::collision::DetectionOutput* ContinuousTriangleIntersection::computeDetectionOutput (void)
00140 {
00141     SReal t[3], u[3], v[3];
00142     double dt = 0.01; //Scene::getInstance()->getDt();
00143 
00144     for (int i = 0; i < 3; i++)
00145         t[i] = u[i] = v[i] = 0.0;
00146 
00147     intersectPointTriangle(t[0], u[0], v[0], tr2.p1(), tr2.v1(), tr1.p1(), tr1.v1(), tr1.p2(), tr1.v2(), tr1.p3(), tr1.v3(), dt);
00148     intersectPointTriangle(t[1], u[1], v[1], tr2.p2(), tr2.v2(), tr1.p1(), tr1.v1(), tr1.p2(), tr1.v2(), tr1.p3(), tr1.v3(), dt);
00149     intersectPointTriangle(t[2], u[2], v[2], tr2.p3(), tr2.v3(), tr1.p1(), tr1.v1(), tr1.p2(), tr1.v2(), tr1.p3(), tr1.v3(), dt);
00150     
00151     // std::cout << "t = "  << t[0] << " " << t[1] << " " << t[2] << std::endl;
00152 
00153     intersectPointTriangle(t[0], u[0], v[0], tr1.p1(), tr1.v1(), tr2.p1(), tr2.v1(), tr2.p2(), tr2.v2(), tr2.p3(), tr2.v3(), dt);
00154     intersectPointTriangle(t[1], u[1], v[1], tr1.p2(), tr1.v2(), tr2.p1(), tr2.v1(), tr2.p2(), tr2.v2(), tr2.p3(), tr2.v3(), dt);
00155     intersectPointTriangle(t[2], u[2], v[2], tr1.p3(), tr1.v3(), tr2.p1(), tr2.v1(), tr2.p2(), tr2.v2(), tr2.p3(), tr2.v3(), dt);
00156     
00157     // std::cout << "t = "  << t[0] << " " << t[1] << " " << t[2] << std::endl;
00158 
00159     intersectEdgeEdge(t[0], u[0], v[0], tr1.p1(), tr1.p2(), tr1.v1(), tr1.v2(), tr2.p1(), tr2.p2(), tr2.v1(), tr2.v2(), dt);
00160     intersectEdgeEdge(t[1], u[1], v[1], tr1.p1(), tr1.p3(), tr1.v1(), tr1.v3(), tr2.p1(), tr2.p2(), tr2.v1(), tr2.v2(), dt);
00161     intersectEdgeEdge(t[2], u[2], v[2], tr1.p2(), tr1.p3(), tr1.v2(), tr1.v3(), tr2.p1(), tr2.p2(), tr2.v1(), tr2.v2(), dt);
00162     
00163     // std::cout << "t = "  << t[0] << " " << t[1] << " " << t[2] << std::endl;
00164 
00165     intersectEdgeEdge(t[0], u[0], v[0], tr1.p1(), tr1.p2(), tr1.v1(), tr1.v2(), tr2.p1(), tr2.p3(), tr2.v1(), tr2.v3(), dt);
00166     intersectEdgeEdge(t[1], u[1], v[1], tr1.p1(), tr1.p3(), tr1.v1(), tr1.v3(), tr2.p1(), tr2.p3(), tr2.v1(), tr2.v3(), dt);
00167     intersectEdgeEdge(t[2], u[2], v[2], tr1.p2(), tr1.p3(), tr1.v2(), tr1.v3(), tr2.p1(), tr2.p3(), tr2.v1(), tr2.v3(), dt);
00168     
00169     // std::cout << "t = "  << t[0] << " " << t[1] << " " << t[2] << std::endl;
00170 
00171     intersectEdgeEdge(t[0], u[0], v[0], tr1.p1(), tr1.p2(), tr1.v1(), tr1.v2(), tr2.p2(), tr2.p3(), tr2.v2(), tr2.v3(), dt);
00172     intersectEdgeEdge(t[1], u[1], v[1], tr1.p1(), tr1.p3(), tr1.v1(), tr1.v3(), tr2.p2(), tr2.p3(), tr2.v2(), tr2.v3(), dt);
00173     intersectEdgeEdge(t[2], u[2], v[2], tr1.p2(), tr1.p3(), tr1.v2(), tr1.v3(), tr2.p2(), tr2.p3(), tr2.v2(), tr2.v3(), dt);
00174 
00175     // compute the point and so on
00176     core::componentmodel::collision::DetectionOutput *detectionOutput = new core::componentmodel::collision::DetectionOutput();
00177     detectionOutput->elem = std::pair<core::CollisionElementIterator, core::CollisionElementIterator>(tr1, tr2);
00178 
00179     return detectionOutput;
00180 }
00181 
00182 ContinuousTriangleIntersection::ContinuousTriangleIntersection(Triangle& t1, Triangle &t2):tr1(t1), tr2(t2),m_tolerance((SReal)(1e-6))
00183 {
00184     m_tolmin = -m_tolerance;
00185     m_tolmax = (SReal)1.0 + m_tolerance;
00186 }
00187 
00189 ContinuousTriangleIntersection::~ContinuousTriangleIntersection()
00190 {
00191 
00192 }
00193 
00203 int ContinuousTriangleIntersection::intersectEdgeEdge (SReal& t, SReal& u, SReal& v,
00204                                                       const Vector3& p1, const Vector3& p2, 
00205                                                       const Vector3& v1, const Vector3& v2,
00206                                                       const Vector3& p3, const Vector3& p4,
00207                                                       const Vector3& v3, const Vector3& v4,
00208                                                       double dt)
00209 {
00210     Vector3 d12, d13, d34, x12, x13, x34;
00211     SReal N1x, N1y, N1z, N2x, N2y, N2z, N3x, N3y, N3z;
00212     SReal C[4];
00213     Vector3 roots(-10,-10,-10);
00214     int numRoots;
00215 
00216     d12 = (v2 - v1)*dt;
00217     d34 = (v4 - v3)*dt;
00218     d13 = (v3 - v1)*dt;
00219     x12 = p2 - p1;
00220     x13 = p3 - p1;
00221     x34 = p4 - p3;
00222 
00230 
00231     N1x = d12[1]*d34[2] - d12[2]*d34[1];
00232     N2x = x12[1]*d34[2] + d12[1]*x34[2] - x12[2]*d34[1] - x34[1]*d12[2];
00233     N3x = x12[1]*x34[2] - x12[2]*x34[1];
00234 
00235     N1y = d12[2]*d34[0] - d12[0]*d34[2];
00236     N2y = x12[2]*d34[0] + d12[2]*x34[0] - x12[0]*d34[2] - x34[2]*d12[0];
00237     N3y = x12[2]*x34[0] - x12[0]*x34[2];
00238 
00239     N1z = d12[0]*d34[1] - d12[1]*d34[0];
00240     N2z = x12[0]*d34[1] + d12[0]*x34[1] - x12[1]*d34[0] - x34[0]*d12[1];
00241     N3z = x12[0]*x34[1] - x12[1]*x34[0];
00242 
00247 
00248     C[3] = d13[0]*N1x + d13[1]*N1y + d13[2]*N1z;
00249     C[2] = x13[0]*N1x + d13[0]*N2x + x13[1]*N1y + d13[1]*N2y + x13[2]*N1z + d13[2]*N2z;
00250     C[1] = x13[0]*N2x + d13[0]*N3x + x13[1]*N2y + d13[1]*N3y + x13[2]*N2z + d13[2]*N3z;
00251     C[0] = x13[0]*N3x + x13[1]*N3y + x13[2]*N3z;
00252 
00254     if (C[3] < -EPSILON || C[3] > EPSILON)
00255         numRoots = solveCubic( roots, C );
00257     else
00258         numRoots = solveQuadratic(roots[0], roots[1], C[2], C[1], C[0]);
00259 
00261     bool isCorrectTime = checkValidRoots (t,
00262                                           numRoots,
00263                                           roots,
00264                                           m_tolmin,
00265                                           m_tolmax);
00266 
00267     if (!isCorrectTime)
00268         return 0;
00269 
00273     x12 += d12*t;
00274     x34 += d34*t;
00275     x13 += d13*t;
00276 
00278 
00279     SReal det = dot(x12, x12) * dot(x34, x34) - dot(x12, x34) * dot(x12, x34);
00280 
00281     if (det > -EPSILON && det < EPSILON)
00282     {
00283         std::cerr << "~ContinuousTriangleIntersection::intersectEdgeEdge: POSSIBLY PARALLEL EDGES, CANNOT FIND DETERMINANT" << std::endl;
00284 
00285         return 0;
00286     }
00287 
00288     SReal inv_det = (SReal)1.0/det;
00289     u = inv_det*(dot(x12, x13) * dot(x34,x34) - dot(x12, x34) * dot(x13, x34));
00290 
00291     if (u < m_tolmin || u > m_tolmax)
00292         return 0;
00293 
00294     v = inv_det*(dot(x12, x34) * dot(x12, x13) - dot(x12, x12) * dot(x13, x34) );
00295 
00296     if (v < m_tolmin || v > m_tolmax)
00297         return 0;
00298 
00299     return 1;
00300 }
00301 
00310 int ContinuousTriangleIntersection::intersectPointTriangle (SReal& t, SReal& u, SReal& v,
00311                                                             const Vector3& p0, const Vector3& v0,
00312                                                             const Vector3& p1, const Vector3& v1,
00313                                                             const Vector3& p2, const Vector3& v2,
00314                                                             const Vector3& p3, const Vector3& v3,
00315                                                             double dt)
00316 {
00317     Vector3 p12, v12, p13, v13, p01, v01;
00318     SReal N1x, N1y, N1z, N2x, N2y, N2z, N3x, N3y, N3z;
00319     SReal C[4];
00320     Vector3 roots(-10,-10,-10);
00321 
00329 
00330     p12 = p2 - p1;
00331     p13 = p3 - p1;
00332     p01 = p1 - p0;
00333 
00334     v12 = (v2 - v1) * dt;
00335     v13 = (v3 - v1) * dt;
00336     v01 = (v1 - v0) * dt;
00337 
00338     N1x = v12[1]*v13[2] - v12[2]*v13[1];
00339     N2x = p12[1]*v13[2] + v12[1]*p13[2] - p12[2]*v13[1] - p13[1]*v12[2];
00340     N3x = p12[1]*p13[2] - p12[2]*p13[1];
00341 
00342     N1y = v12[2]*v13[0] - v12[0]*v13[2];
00343     N2y = p12[2]*v13[0] + v12[2]*p13[0] - p12[0]*v13[2] - p13[2]*v12[0];
00344     N3y = p12[2]*p13[0] - p12[0]*p13[2];
00345 
00346     N1z = v12[0]*v13[1] - v12[1]*v13[0];
00347     N2z = p12[0]*v13[1] + v12[0]*p13[1] - p12[1]*v13[0] - p13[0]*v12[1];
00348     N3z = p12[0]*p13[1] - p12[1]*p13[0];
00349 
00354 
00355     C[3] = v01[0]*N1x + v01[1]*N1y + v01[2]*N1z;
00356     C[2] = p01[0]*N1x + v01[0]*N2x + p01[1]*N1y + v01[1]*N2y + p01[2]*N1z + v01[2]*N2z;
00357     C[1] = p01[0]*N2x + v01[0]*N3x + p01[1]*N2y + v01[1]*N3y + p01[2]*N2z + v01[2]*N3z;
00358     C[0] = p01[0]*N3x + p01[1]*N3y + p01[2]*N3z;
00359 
00360     int numRoots;
00361 
00363     if (C[3] < -EPSILON || C[3] > EPSILON)
00364         numRoots = solveCubic (roots, C);
00366     else
00367         numRoots = solveQuadratic (roots[0], roots[1], C[2], C[1], C[0]);
00368 
00370     bool isCorrectTime = checkValidRoots (t, numRoots, roots, m_tolmin, m_tolmax);
00371 
00372     if (!isCorrectTime)
00373         return 0;
00374 
00378 
00379     Vector3 x4 = p0 + v0*t*dt;
00380     Vector3 x1 = p1 + v1*t*dt;
00381     Vector3 x2 = p2 + v2*t*dt;
00382     Vector3 x3 = p3 + v3*t*dt;
00383 
00384     Vector3 x43 = x3 - x4;
00385     Vector3 x13 = x3 - x1;
00386     Vector3 x23 = x3 - x2;
00387 
00389     SReal det = dot (x13, x13) * dot(x23, x23) - dot(x13, x23) * dot(x13, x23);
00390 
00391     if (det > -EPSILON && det < EPSILON)
00392     {
00393         std::cerr << "ContinousTriangleIntersection::intersectPointTriangle: POSSIBLY POINT IS PARALLEL TO PLANE, CANNOT FIND DETERMINANT" << std::endl;
00394         return 0;
00395     }
00396 
00398     SReal inv_det = (SReal)1./det;
00399     u = inv_det * ( dot (x13, x43) * dot(x23, x23) - dot(x13, x23) * dot (x23, x43) );
00400 
00401     if (u < m_tolmin || u > m_tolmax)
00402     {
00403         t = -10;
00404         return 0;
00405     }
00406 
00407     v = inv_det * ( dot(x13, x13) * dot(x23, x43) - dot(x13, x23) * dot(x13, x43) );
00408 
00409     if (v < m_tolmin || u + v > m_tolmax)
00410     {
00411         t = -10;
00412         return 0;
00413     }
00414 
00415     return 1;
00416 }
00417 
00423 int ContinuousTriangleIntersection::solveCubic (Vector3& s, SReal c[4] )
00424 {
00425     int   i, num;
00426     SReal sub;
00427     SReal A, B, C;
00428     SReal sq_A, p, q;
00429     SReal cb_p, D;
00430 
00432 
00433     A = c[ 2 ] / c[ 3 ];
00434     B = c[ 1 ] / c[ 3 ];
00435     C = c[ 0 ] / c[ 3 ];
00436 
00439 
00440     sq_A = A * A;
00441     p = (SReal)1.0/3 * ((SReal)(-1.0/3) * sq_A + B);
00442     q = (SReal)1.0/2 * ((SReal)(2.0/27) * A * sq_A - (SReal)(1.0/3) * A * B + C);
00443 
00445 
00446     cb_p = p * p * p;
00447     D = q * q + cb_p;
00448 
00449     if (IsZero(D))
00450     {
00451         if (IsZero(q)) 
00452         {
00453             s[ 0 ] = 0;
00454             num = 1;
00455         }
00456         else 
00457         {
00458             SReal u = cbrt(-q);
00459             s[ 0 ] = 2 * u;
00460             s[ 1 ] = - u;
00461             num = 2;
00462         }
00463     }
00464     else if (D < 0) 
00465     {
00466         SReal phi = (SReal)1.0/3 * acos(-q / sqrt(-cb_p));
00467         SReal t = 2 * sqrt(-p);
00468 
00469         s[ 0 ] =   t * cos(phi);
00470         s[ 1 ] = - t * cos(phi + (SReal)R_PI / 3);
00471         s[ 2 ] = - t * cos(phi - (SReal)R_PI / 3);
00472         num = 3;
00473     }
00474     else 
00475     {
00476         SReal sqrt_D = sqrt(D);
00477         SReal u = cbrt(sqrt_D - q);
00478         SReal v = - cbrt(sqrt_D + q);
00479 
00480         s[ 0 ] = u + v;
00481         num = 1;
00482     }
00483 
00485 
00486     sub = (SReal)1.0/3 * A;
00487 
00488     for (i = 0; i < num; ++i)
00489         s[ i ] -= sub;
00490 
00491     return num;
00492 }
00493 
00494 
00501 int ContinuousTriangleIntersection::solveQuadratic (SReal& t1, SReal& t2, const SReal& a,
00502                                                    const SReal& b, const SReal& c)
00503 {
00504     int numRoots=0;
00505     SReal delta = b*b - (SReal)4.0*a*c;
00506     if (delta < 0.0)
00507         return 0;
00508 
00509     SReal sqrt_delta = sqrt(delta);
00510 
00511     SReal sgn_b;
00512     if (b<0.0)
00513         sgn_b=-1.0;
00514     else
00515         sgn_b=1.0;
00516 
00517     SReal q = (SReal)(-0.5)*(b+sgn_b*sqrt_delta);
00518 
00519     if (a < -EPSILON || a > EPSILON)
00520     {
00521         t2 = q/a;
00522         numRoots++;
00523     }
00524 
00525     if (q < -EPSILON || q > EPSILON)
00526     {
00527         t1 = c/q;
00528 
00529         numRoots++;
00530     }
00531     //else
00532     //    std::cerr << "ContinousTriangleIntersection::solveQuadratic: UNSOLVABLE QUADRATIC EQUATION" << std::endl;
00533 
00534 
00535     return numRoots;
00536 }
00537 
00542 bool ContinuousTriangleIntersection::checkValidRoots(SReal& validRoot,
00543                                                     const int& numRoots,
00544                                                     const Vector3& roots,
00545                                                     const SReal& rootMin,
00546                                                     const SReal& rootMax)
00547 {
00548     validRoot=-10;
00549     
00551     if ((numRoots == 1) && checkRange (roots[0], rootMin, rootMax))
00552     {
00553         validRoot = roots[0];
00554         return true;
00555     }
00557     else if (numRoots == 2)
00558     {
00559         if (checkRange(roots[0], rootMin, rootMax) && checkRange(roots[1], rootMin, rootMax))
00560         {
00561             validRoot = getMinVal(roots[0], roots[1]);
00562             return true;
00563         }
00564         else if (checkRange (roots[0], rootMin, rootMax))
00565         {
00566             validRoot = roots[0];
00567             return true;
00568         }
00569         else if (checkRange (roots[1], rootMin, rootMax))
00570         {
00571             validRoot = roots[1];
00572             return true;
00573         }
00574         else
00575             return false;
00576     }
00578     else if (numRoots == 3)
00579     {
00580         if (checkRange (roots[0], rootMin, rootMax) &&
00581             checkRange (roots[1], rootMin, rootMax) &&
00582             checkRange (roots[2], rootMin, rootMax))
00583         {
00584             validRoot = getMinVal(roots[0], roots[1], roots[2]);
00585             return true;
00586         }
00587         else if (checkRange (roots[0], rootMin, rootMax) &&
00588                  checkRange (roots[1], rootMin, rootMax))
00589         {
00590             validRoot = getMinVal(roots[0], roots[1]);
00591             return true;
00592         }
00593         else if (checkRange (roots[1], rootMin, rootMax) &&
00594                  checkRange (roots[2], rootMin, rootMax))
00595         {
00596             validRoot = getMinVal(roots[1], roots[2]);
00597             return true;
00598         }
00599         else if (checkRange (roots[0], rootMin, rootMax) &&
00600                  checkRange (roots[2], rootMin, rootMax))
00601         {
00602             validRoot = getMinVal(roots[0], roots[2]);
00603             return true;
00604         }
00605         else if (checkRange (roots[0], rootMin, rootMax))
00606         {
00607             validRoot = roots[0];
00608             return true;
00609         }
00610         else if (checkRange (roots[1], rootMin, rootMax))
00611         {
00612             validRoot = roots[1];
00613             return true;
00614         }
00615         else if (checkRange (roots[2], rootMin, rootMax))
00616         {
00617             validRoot = roots[2];
00618             return true;
00619         }
00620         else
00621             return false;
00622     }
00623     else
00624         return false;
00625 }
00626 
00627 } // namespace collision
00628 
00629 } // namespace component
00630 
00631 } // namespace sofa
00632 

Generated on Sun Nov 23 02:33:11 2008 for Sofa by  doxygen 1.5.7.1