MinProximityIntersection.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/helper/system/config.h>
00026 #include <sofa/component/collision/MinProximityIntersection.h>
00027 #include <sofa/core/ObjectFactory.h>
00028 #include <sofa/component/collision/proximity.h>
00029 #include <sofa/defaulttype/Mat.h>
00030 #include <sofa/defaulttype/Vec.h>
00031 #include <sofa/core/componentmodel/collision/Intersection.inl>
00032 //#include <sofa/component/collision/RayPickInteractor.h>
00033 #include <iostream>
00034 #include <algorithm>
00035 #include <sofa/helper/gl/template.h>
00036 
00037 #define DYNAMIC_CONE_ANGLE_COMPUTATION
00038 
00039 namespace sofa
00040 {
00041 
00042 namespace component
00043 {
00044 
00045 namespace collision
00046 {
00047 
00048 using namespace sofa::defaulttype;
00049 using namespace sofa::core::componentmodel::collision;
00050 using namespace helper;
00051 
00052 SOFA_DECL_CLASS(MinProximityIntersection)
00053 
00054 int MinProximityIntersectionClass = core::RegisterObject("TODO-MinProximityIntersection")
00055 .add< MinProximityIntersection >()
00056 ;
00057 
00058 MinProximityIntersection::MinProximityIntersection()
00059 : useSphereTriangle(initData(&useSphereTriangle, true, "useSphereTriangle","activate Sphere-Triangle intersection tests"))
00060 , usePointPoint(initData(&usePointPoint, true, "usePointPoint","activate Point-Point intersection tests"))
00061 , alarmDistance(initData(&alarmDistance, 1.0, "alarmDistance","Proximity detection distance"))
00062 , contactDistance(initData(&contactDistance, 0.5, "contactDistance","Distance below which a contact is created"))
00063 {
00064 }
00065 
00066 void MinProximityIntersection::init()
00067 {
00068     intersectors.add<CubeModel, CubeModel, MinProximityIntersection>(this);
00069     if (usePointPoint.getValue())
00070         intersectors.add<PointModel, PointModel, MinProximityIntersection>(this);
00071     else
00072         intersectors.ignore<PointModel, PointModel>();
00073     intersectors.add<LineModel, LineModel, MinProximityIntersection>(this);
00074     intersectors.add<LineModel, PointModel, MinProximityIntersection>(this);
00075     intersectors.add<TriangleModel, PointModel, MinProximityIntersection>(this);
00076     intersectors.ignore<TriangleModel, LineModel>();
00077     intersectors.ignore<TriangleModel, TriangleModel>();
00078     if (useSphereTriangle.getValue())
00079     {
00080         intersectors.add<SphereModel, PointModel, MinProximityIntersection>(this);
00081         intersectors.add<TriangleModel, SphereModel, MinProximityIntersection>(this);
00082         intersectors.add<LineModel, SphereModel, MinProximityIntersection>(this);
00083     }
00084     else
00085     {
00086         intersectors.ignore<SphereModel, PointModel>();
00087         intersectors.ignore<LineModel, SphereModel>();
00088         intersectors.ignore<TriangleModel, SphereModel>();
00089     }
00090     intersectors.ignore<RayModel, PointModel>();
00091     intersectors.ignore<RayModel, LineModel>();
00092     //intersectors.add<RayModel, TriangleModel, MinProximityIntersection>(this);
00093 }
00094 
00095 bool MinProximityIntersection::testIntersection(Cube &cube1, Cube &cube2)
00096 {
00097     const Vector3& minVect1 = cube1.minVect();
00098     const Vector3& minVect2 = cube2.minVect();
00099     const Vector3& maxVect1 = cube1.maxVect();
00100     const Vector3& maxVect2 = cube2.maxVect();
00101 
00102     const double alarmDist = getAlarmDistance() + cube1.getProximity() + cube2.getProximity();
00103 
00104     for (int i=0;i<3;i++)
00105     {
00106         if ( minVect1[i] > maxVect2[i] + alarmDist || minVect2[i]> maxVect1[i] + alarmDist )
00107             return false;
00108     }
00109 
00110     return true;
00111 }
00112 
00113 int MinProximityIntersection::computeIntersection(Cube&, Cube&, OutputVector* /*contacts*/)
00114 {
00115     return 0; 
00116 }
00117 
00118 bool MinProximityIntersection::testIntersection(Line& e1, Line& e2)
00119 {
00120     const double alarmDist = getAlarmDistance() + e1.getProximity() + e2.getProximity();
00121     
00122     const Vector3 AB = e1.p2()-e1.p1();
00123     const Vector3 CD = e2.p2()-e2.p1();
00124     const Vector3 AC = e2.p1()-e1.p1();
00125     Matrix2 A;
00126     Vector2 b;
00127 
00128     A[0][0] = AB*AB;
00129     A[1][1] = CD*CD;
00130     A[0][1] = A[1][0] = -CD*AB;
00131     b[0] = AB*AC;
00132     b[1] = -CD*AC;
00133 
00134     const double det = determinant(A);
00135 
00136     double alpha = 0.5;
00137     double beta = 0.5;
00138 
00139     if (det < -1.0e-18 || det > 1.0e-18)
00140     {
00141         alpha = (b[0]*A[1][1] - b[1]*A[0][1])/det;
00142         beta  = (b[1]*A[0][0] - b[0]*A[1][0])/det;
00143         if (alpha < 0.000001 || alpha > 0.999999 ||
00144             beta  < 0.000001 || beta  > 0.999999 )
00145             return false;
00146     }
00147 
00148     Vector3 PQ = AC + CD * beta - AB * alpha;
00149 
00150     if (PQ.norm2() < alarmDist*alarmDist)
00151         return true;
00152     else
00153         return false;
00154 }
00155 
00156 int MinProximityIntersection::computeIntersection(Line& e1, Line& e2, OutputVector* contacts)
00157 {
00158     const double alarmDist = getAlarmDistance() + e1.getProximity() + e2.getProximity();
00159 
00160     const Vector3 AB = e1.p2()-e1.p1();
00161     const Vector3 CD = e2.p2()-e2.p1();
00162     const Vector3 AC = e2.p1()-e1.p1();
00163     Matrix2 A;
00164     Vector2 b;
00165 
00166     A[0][0] = AB*AB;
00167     A[1][1] = CD*CD;
00168     A[0][1] = A[1][0] = -CD*AB;
00169     b[0] = AB*AC;
00170     b[1] = -CD*AC;
00171     const double det = determinant(A);
00172 
00173     double alpha = 0.5;
00174     double beta = 0.5;
00175 
00176     if (det < -1.0e-15 || det > 1.0e-15)
00177     {
00178         alpha = (b[0]*A[1][1] - b[1]*A[0][1])/det;
00179         beta  = (b[1]*A[0][0] - b[0]*A[1][0])/det;
00180         if (alpha < 0.000001 || alpha > 0.999999 ||
00181             beta  < 0.000001 || beta  > 0.999999 )
00182             return 0;
00183     }
00184 
00185     Vector3 P,Q,PQ;
00186     P = e1.p1() + AB * alpha;
00187     Q = e2.p1() + CD * beta;
00188     PQ = Q-P;
00189 
00190     if (PQ.norm2() >= alarmDist*alarmDist)
00191         return 0;
00192 
00193 #ifdef DETECTIONOUTPUT_FREEMOTION
00194 
00195     Vector3 Pfree,Qfree,ABfree,CDfree;
00196     ABfree = e1.p2Free()-e1.p1Free();
00197     CDfree = e2.p2Free()-e2.p1Free();
00198     Pfree = e1.p1Free() + ABfree * alpha;
00199     Qfree = e2.p1Free() + CDfree * beta;
00200 
00201 #endif
00202 
00203     const double contactDist = getContactDistance() + e1.getProximity() + e2.getProximity();
00204 
00205     contacts->resize(contacts->size()+1);
00206     DetectionOutput *detection = &*(contacts->end()-1);
00207     detection->elem = std::pair<core::CollisionElementIterator, core::CollisionElementIterator>(e1, e2);
00208     detection->id = (e1.getCollisionModel()->getSize() > e2.getCollisionModel()->getSize()) ? e1.getIndex() : e2.getIndex();
00209     detection->point[0]=P;
00210     detection->point[1]=Q;
00211 #ifdef DETECTIONOUTPUT_FREEMOTION
00212     detection->freePoint[0]=Pfree;
00213     detection->freePoint[1]=Qfree;
00214 #endif
00215     detection->normal=PQ;
00216     detection->value = detection->normal.norm();
00217     detection->normal /= detection->value;
00218     detection->value -= contactDist;
00219     return 1;
00220 }
00221 
00222 bool MinProximityIntersection::testIntersection(Triangle& e2, Point& e1)
00223 {
00224     const double alarmDist = getAlarmDistance() + e1.getProximity() + e2.getProximity();
00225 
00226     const Vector3 AB = e2.p2()-e2.p1();
00227     const Vector3 AC = e2.p3()-e2.p1();
00228     const Vector3 AP = e1.p() -e2.p1();
00229     Matrix2 A;
00230     Vector2 b;
00231 
00232     // We want to find alpha,beta so that:
00233     // AQ = AB*alpha+AC*beta
00234     // PQ.AB = 0 and PQ.AC = 0
00235     // (AQ-AP).AB = 0 and (AQ-AP).AC = 0
00236     // AQ.AB = AP.AB and AQ.AC = AP.AC
00237     //
00238     // (AB*alpha+AC*beta).AB = AP.AB and
00239     // (AB*alpha+AC*beta).AC = AP.AC
00240     //
00241     // AB.AB*alpha + AC.AB*beta = AP.AB and
00242     // AB.AC*alpha + AC.AC*beta = AP.AC
00243     //
00244     // A . [alpha beta] = b
00245     A[0][0] = AB*AB;
00246     A[1][1] = AC*AC;
00247     A[0][1] = A[1][0] = AB*AC;
00248     b[0] = AP*AB;
00249     b[1] = AP*AC;
00250     const double det = determinant(A);
00251 
00252     double alpha = 0.5;
00253     double beta = 0.5;
00254 
00255     //if (det < -0.000000000001 || det > 0.000000000001)
00256     {
00257         alpha = (b[0]*A[1][1] - b[1]*A[0][1])/det;
00258         beta  = (b[1]*A[0][0] - b[0]*A[1][0])/det;
00259         if (alpha < 0.000001 ||
00260             beta  < 0.000001 ||
00261             alpha + beta  > 0.999999)
00262             return false;
00263     }
00264 
00265     const Vector3 PQ = AB * alpha + AC * beta - AP;
00266 
00267     if (PQ.norm2() < alarmDist*alarmDist)
00268         return true;
00269     else
00270         return false;
00271 }
00272 
00273 int MinProximityIntersection::computeIntersection(Triangle& e2, Point& e1, OutputVector* contacts)
00274 {
00275     const double alarmDist = getAlarmDistance() + e1.getProximity() + e2.getProximity();
00276 
00277     const Vector3 AB = e2.p2()-e2.p1();
00278     const Vector3 AC = e2.p3()-e2.p1();
00279     const Vector3 AP = e1.p() -e2.p1();
00280     Matrix2 A;
00281     Vector2 b;
00282 
00283     A[0][0] = AB*AB;
00284     A[1][1] = AC*AC;
00285     A[0][1] = A[1][0] = AB*AC;
00286     b[0] = AP*AB;
00287     b[1] = AP*AC;
00288 
00289     const double det = determinant(A);
00290 
00291     double alpha = 0.5;
00292     double beta = 0.5;
00293 
00294     //if (det < -0.000000000001 || det > 0.000000000001)
00295     {
00296         alpha = (b[0]*A[1][1] - b[1]*A[0][1])/det;
00297         beta  = (b[1]*A[0][0] - b[0]*A[1][0])/det;
00298         if (alpha < 0.000001 ||
00299             beta  < 0.000001 ||
00300             alpha + beta  > 0.999999)
00301             return 0;
00302     }
00303 
00304     Vector3 P,Q,QP; //PQ
00305     P = e1.p();
00306     Q = e2.p1() + AB * alpha + AC * beta;
00307     QP = P-Q;
00308 
00309     if (QP.norm2() >= alarmDist*alarmDist)
00310         return 0;
00311 
00312     Vector3 PQ = Q-P;
00313 
00314 
00315 #ifdef DETECTIONOUTPUT_FREEMOTION
00316 
00317     Vector3 Pfree,Qfree,ABfree,ACfree;
00318     ABfree = e2.p2Free()-e2.p1Free();
00319     ACfree = e2.p3Free()-e2.p1Free();
00320     Pfree = e1.pFree();
00321     Qfree = e2.p1Free() + ABfree * alpha + ACfree * beta;
00322 
00323 #endif
00324 
00325     const double contactDist = getContactDistance() + e1.getProximity() + e2.getProximity();
00326 
00327     contacts->resize(contacts->size()+1);
00328     DetectionOutput *detection = &*(contacts->end()-1);
00329     detection->elem = std::pair<core::CollisionElementIterator, core::CollisionElementIterator>(e2, e1);
00330     detection->id = e1.getIndex();
00331     detection->point[0]=Q;
00332     detection->point[1]=P;
00333 #ifdef DETECTIONOUTPUT_FREEMOTION
00334     detection->freePoint[0]=Qfree;
00335     detection->freePoint[1]=Pfree;
00336 #endif
00337     detection->normal = QP;
00338     detection->value = detection->normal.norm();
00339     detection->normal /= detection->value;
00340     detection->value -= contactDist;
00341     return 1;
00342 }
00343 
00344 bool MinProximityIntersection::testIntersection(Line& e2, Point& e1)
00345 {
00346 
00347     const double alarmDist = getAlarmDistance() + e1.getProximity() + e2.getProximity();
00348     const Vector3 AB = e2.p2()-e2.p1();
00349     const Vector3 AP = e1.p()-e2.p1();
00350 
00351     double A;
00352     double b;
00353     A = AB*AB;
00354     b = AP*AB;
00355 
00356     double alpha = 0.5;
00357 
00358     //if (A < -0.000001 || A > 0.000001)
00359     {
00360         alpha = b/A;
00361         if (alpha < 0.000001 || alpha > 0.999999)
00362             return false;
00363     }
00364 
00365     Vector3 P,Q,PQ;
00366     P = e1.p();
00367     Q = e2.p1() + AB * alpha;
00368     PQ = Q-P;
00369 
00370     if (PQ.norm2() < alarmDist*alarmDist)
00371         return true;
00372     else
00373         return false;
00374 }
00375 
00376 int MinProximityIntersection::computeIntersection(Line& e2, Point& e1, OutputVector* contacts)
00377 {
00378     const double alarmDist = getAlarmDistance() + e1.getProximity() + e2.getProximity();
00379     const Vector3 AB = e2.p2()-e2.p1();
00380     const Vector3 AP = e1.p()-e2.p1();
00381 
00382     double A;
00383     double b;
00384     A = AB*AB;
00385     b = AP*AB;
00386 
00387     double alpha = 0.5;
00388 
00389     //if (A < -0.000001 || A > 0.000001)
00390     {
00391         alpha = b/A;
00392         if (alpha < 0.000001 || alpha > 0.999999)
00393             return 0;
00394     }
00395 
00396     Vector3 P,Q,QP;
00397     P = e1.p();
00398     Q = e2.p1() + AB * alpha;
00399     QP = P-Q;
00400 
00401     if (QP.norm2() >= alarmDist*alarmDist)
00402         return 0;
00403 
00404     Vector3 PQ = Q-P;
00405 
00406 #ifdef DETECTIONOUTPUT_FREEMOTION
00407 
00408 
00409     Vector3 ABfree = e2.p2Free()-e2.p1Free();
00410     Vector3 Pfree = e1.pFree();
00411     Vector3 Qfree = e2.p1Free() + ABfree * alpha;
00412 
00413 #endif
00414 
00415     const double contactDist = getContactDistance() + e1.getProximity() + e2.getProximity();
00416 
00417     contacts->resize(contacts->size()+1);
00418     DetectionOutput *detection = &*(contacts->end()-1);
00419     
00420     detection->elem = std::pair<core::CollisionElementIterator, core::CollisionElementIterator>(e2, e1);
00421     detection->id = e1.getIndex();
00422     detection->point[0]=Q;
00423     detection->point[1]=P;
00424 #ifdef DETECTIONOUTPUT_FREEMOTION
00425     detection->freePoint[0]=Qfree;
00426     detection->freePoint[1]=Pfree;
00427 #endif
00428     detection->normal=QP;
00429     detection->value = detection->normal.norm();
00430     detection->normal /= detection->value;
00431     detection->value -= contactDist;
00432     return 1;
00433 }
00434 
00435 bool MinProximityIntersection::testIntersection(Point& e1, Point& e2)
00436 {
00437     const double alarmDist = getAlarmDistance() + e1.getProximity() + e2.getProximity();
00438 
00439     Vector3 PQ = e2.p()-e1.p();
00440 
00441     if (PQ.norm2() < alarmDist*alarmDist)
00442         return true;
00443     else
00444         return false;
00445 }
00446 
00447 int MinProximityIntersection::computeIntersection(Point& e1, Point& e2, OutputVector* contacts)
00448 {
00449 
00450     const double alarmDist = getAlarmDistance() + e1.getProximity() + e2.getProximity();
00451 
00452     Vector3 P,Q,PQ;
00453     P = e1.p();
00454     Q = e2.p();
00455     PQ = Q-P;
00456 
00457     #ifdef DETECTIONOUTPUT_FREEMOTION
00458     Vector3 Pfree,Qfree;
00459     Pfree = e1.pFree();
00460     Qfree = e2.pFree();
00461     #endif
00462 
00463 
00464     if (PQ.norm2() >= alarmDist*alarmDist)
00465         return 0;
00466 
00467     const double contactDist = getContactDistance() + e1.getProximity() + e2.getProximity();
00468 
00469     contacts->resize(contacts->size()+1);
00470     DetectionOutput *detection = &*(contacts->end()-1);
00471     detection->elem = std::pair<core::CollisionElementIterator, core::CollisionElementIterator>(e1, e2);
00472     detection->id = (e1.getCollisionModel()->getSize() > e2.getCollisionModel()->getSize()) ? e1.getIndex() : e2.getIndex();
00473     detection->point[0]=P;
00474     detection->point[1]=Q;
00475 #ifdef DETECTIONOUTPUT_FREEMOTION
00476     detection->freePoint[0]=Pfree;
00477     detection->freePoint[1]=Qfree;
00478 #endif
00479     detection->normal=PQ;
00480     detection->value = detection->normal.norm();
00481     detection->normal /= detection->value;
00482     detection->value -= contactDist;
00483     return 1;
00484 }
00485 
00486 
00487 
00488 bool MinProximityIntersection::testIntersection(Triangle& e2, Sphere& e1)
00489 {
00490     const double alarmDist = getAlarmDistance() + e1.r() + e1.getProximity() + e2.getProximity();
00491 
00492     const Vector3 x13 = e2.p1()-e2.p2();
00493     const Vector3 x23 = e2.p1()-e2.p3();
00494     const Vector3 x03 = e2.p1()-e1.center();
00495     Matrix2 A;
00496     Vector2 b;
00497     A[0][0] = x13*x13;
00498     A[1][1] = x23*x23;
00499     A[0][1] = A[1][0] = x13*x23;
00500     b[0] = x13*x03;
00501     b[1] = x23*x03;
00502     const double det = determinant(A);
00503 
00504     double alpha = 0.5;
00505     double beta = 0.5;
00506 
00507     //if (det < -0.000001 || det > 0.000001)
00508     {
00509         alpha = (b[0]*A[1][1] - b[1]*A[0][1])/det;
00510         beta  = (b[1]*A[0][0] - b[0]*A[1][0])/det;
00511         if (alpha < 0.000001 ||
00512             beta  < 0.000001 ||
00513             alpha + beta  > 0.999999)
00514             return false;
00515     }
00516 
00517     Vector3 P,Q,PQ;
00518     P = e1.center();
00519     Q = e2.p1() - x13 * alpha - x23 * beta;
00520     PQ = Q-P;
00521 
00522     if (PQ.norm2() < alarmDist*alarmDist)
00523     {
00524         return true;
00525     }
00526     else
00527         return false;
00528 }
00529 
00530 int MinProximityIntersection::computeIntersection(Triangle& e2, Sphere& e1, OutputVector* contacts)
00531 {
00532     const double alarmDist = getAlarmDistance() + e1.r() + e1.getProximity() + e2.getProximity();
00533 
00534     const Vector3 x13 = e2.p1()-e2.p2();
00535     const Vector3 x23 = e2.p1()-e2.p3();
00536     const Vector3 x03 = e2.p1()-e1.center();
00537     Matrix2 A;
00538     Vector2 b;
00539     A[0][0] = x13*x13;
00540     A[1][1] = x23*x23;
00541     A[0][1] = A[1][0] = x13*x23;
00542     b[0] = x13*x03;
00543     b[1] = x23*x03;
00544     const double det = determinant(A);
00545 
00546     double alpha = 0.5;
00547     double beta = 0.5;
00548 
00549     //if (det < -0.000001 || det > 0.000001)
00550     {
00551         alpha = (b[0]*A[1][1] - b[1]*A[0][1])/det;
00552         beta  = (b[1]*A[0][0] - b[0]*A[1][0])/det;
00553         if (alpha < 0.000001 ||
00554             beta  < 0.000001 ||
00555             alpha + beta  > 0.999999)
00556             return 0;
00557     }
00558 
00559     Vector3 P = e1.center();
00560     Vector3 Q = e2.p1() - x13 * alpha - x23 * beta;
00561     Vector3 QP = P-Q;
00562     Vector3 PQ = Q-P;
00563 
00564     if (QP.norm2() >= alarmDist*alarmDist)
00565         return 0;
00566 
00567     const double contactDist = getContactDistance() + e1.r() + e1.getProximity() + e2.getProximity();
00568 
00569     contacts->resize(contacts->size()+1);
00570     DetectionOutput *detection = &*(contacts->end()-1);
00571     detection->elem = std::pair<core::CollisionElementIterator, core::CollisionElementIterator>(e2, e1);
00572     detection->id = e1.getIndex();
00573     detection->point[0]=Q;
00574     detection->point[1]=P;
00575     detection->normal=QP;
00576     detection->value = detection->normal.norm();
00577     detection->normal /= detection->value;
00578     detection->value -= contactDist;
00579     return 1;
00580 }
00581 
00582 bool MinProximityIntersection::testIntersection(Line& e2, Sphere& e1)
00583 {
00584     const double alarmDist = getAlarmDistance() + e1.r() + e1.getProximity() + e2.getProximity();
00585 
00586     const Vector3 x32 = e2.p1()-e2.p2();
00587     const Vector3 x31 = e1.center()-e2.p2();
00588     double A;
00589     double b;
00590     A = x32*x32;
00591     b = x32*x31;
00592 
00593     double alpha = 0.5;
00594 
00595     //if (A < -0.000001 || A > 0.000001)
00596     {
00597         alpha = b/A;
00598         if (alpha < 0.000001 || alpha > 0.999999)
00599             return false;
00600     }
00601 
00602     Vector3 P,Q,PQ;
00603     P = e1.center();
00604     Q = e2.p1() - x32 * alpha;
00605     PQ = Q-P;
00606 
00607     if (PQ.norm2() < alarmDist*alarmDist)
00608     {
00609         return true;
00610     }
00611     else
00612         return false;
00613 }
00614 
00615 int MinProximityIntersection::computeIntersection(Line& e2, Sphere& e1, OutputVector* contacts)
00616 {
00617     const double alarmDist = getAlarmDistance() + e1.r() + e1.getProximity() + e2.getProximity();
00618 
00619     const Vector3 x32 = e2.p1()-e2.p2();
00620     const Vector3 x31 = e1.center()-e2.p2();
00621     double A;
00622     double b;
00623     A = x32*x32;
00624     b = x32*x31;
00625 
00626     double alpha = 0.5;
00627 
00628     //if (A < -0.000001 || A > 0.000001)
00629     {
00630         alpha = b/A;
00631         if (alpha < 0.000001 || alpha > 0.999999)
00632             return 0;
00633     }
00634 
00635     Vector3 P = e1.center();
00636     Vector3 Q = e2.p1() - x32 * alpha;
00637     Vector3 QP = P-Q;
00638     Vector3 PQ = Q-P;
00639 
00640     if (QP.norm2() >= alarmDist*alarmDist)
00641         return 0;
00642 
00643     const double contactDist = getContactDistance() + e1.r() + e1.getProximity() + e2.getProximity();
00644 
00645     contacts->resize(contacts->size()+1);
00646     DetectionOutput *detection = &*(contacts->end()-1);
00647     detection->elem = std::pair<core::CollisionElementIterator, core::CollisionElementIterator>(e2, e1);
00648     detection->id = e1.getIndex();
00649     detection->point[0]=Q;
00650     detection->point[1]=P;
00651     detection->normal=QP;
00652     detection->value = detection->normal.norm();
00653     detection->normal /= detection->value;
00654     detection->value -= contactDist;
00655     return 1;
00656 }
00657 
00658 bool MinProximityIntersection::testIntersection(Sphere& e1, Point& e2)
00659 {
00660     const double alarmDist = getAlarmDistance() + e1.r() + e1.getProximity() + e2.getProximity();
00661 
00662     Vector3 P,Q,PQ;
00663     P = e1.center();
00664     Q = e2.p();
00665     PQ = Q-P;
00666 
00667     if (PQ.norm2() < alarmDist*alarmDist)
00668     {
00669         return true;
00670     }
00671     else
00672         return false;
00673 }
00674 
00675 int MinProximityIntersection::computeIntersection(Sphere& e1, Point& e2, OutputVector* contacts)
00676 {
00677     const double alarmDist = getAlarmDistance() + e1.r() + e1.getProximity() + e2.getProximity();
00678 
00679     Vector3 P,Q,PQ;
00680     P = e1.center();
00681     Q = e2.p();
00682     PQ = Q-P;
00683     if (PQ.norm2() >= alarmDist*alarmDist)
00684         return 0;
00685 
00686     const double contactDist = getContactDistance() + e1.r() + e1.getProximity() + e2.getProximity();
00687 
00688     contacts->resize(contacts->size()+1);
00689     DetectionOutput *detection = &*(contacts->end()-1);
00690     detection->elem = std::pair<core::CollisionElementIterator, core::CollisionElementIterator>(e1, e2);
00691     detection->id = (e1.getCollisionModel()->getSize() > e2.getCollisionModel()->getSize()) ? e1.getIndex() : e2.getIndex();
00692     detection->point[0]=P;
00693     detection->point[1]=Q;
00694     detection->normal=PQ;
00695     detection->value = detection->normal.norm();
00696     detection->normal /= detection->value;
00697     detection->value -= contactDist;
00698     return 1;
00699 }
00700 /*
00701 bool MinProximityIntersection::testIntersection(Ray &t1,Triangle &t2)
00702 {
00703     Vector3 P,Q,PQ;
00704     static DistanceSegTri proximitySolver;
00705 
00706     const double alarmDist = getAlarmDistance() + t1.getProximity() + t2.getProximity();
00707 
00708     if (fabs(t2.n() * t1.direction()) < 0.000001)
00709         return false; // no intersection for edges parallel to the triangle
00710 
00711     Vector3 A = t1.origin();
00712     Vector3 B = A + t1.direction() * t1.l();
00713 
00714     proximitySolver.NewComputation( &t2, A, B,P,Q);
00715     PQ = Q-P;
00716 
00717     if (PQ.norm2() < alarmDist*alarmDist)
00718     {
00719         //std::cout<<"Collision between Line - Triangle"<<std::endl;
00720         return true;
00721     }
00722     else
00723         return false;
00724 }
00725 
00726 int MinProximityIntersection::computeIntersection(Ray &t1, Triangle &t2, OutputVector* contacts)
00727 {
00728     const double alarmDist = getAlarmDistance() + t1.getProximity() + t2.getProximity();
00729 
00730 
00731     if (fabs(t2.n() * t1.direction()) < 0.000001)
00732         return false; // no intersection for edges parallel to the triangle
00733 
00734     Vector3 A = t1.origin();
00735     Vector3 B = A + t1.direction() * t1.l();
00736 
00737     Vector3 P,Q,PQ;
00738     static DistanceSegTri proximitySolver;
00739 
00740     proximitySolver.NewComputation( &t2, A,B,P,Q);
00741     PQ = Q-P;
00742 
00743     if (PQ.norm2() >= alarmDist*alarmDist)
00744         return 0;
00745 
00746     const double contactDist = alarmDist;
00747     contacts->resize(contacts->size()+1);
00748     DetectionOutput *detection = &*(contacts->end()-1);
00749 
00750     detection->elem = std::pair<core::CollisionElementIterator, core::CollisionElementIterator>(t1, t2);
00751     detection->id = t1.getIndex();
00752     detection->point[1]=P;
00753     detection->point[0]=Q;
00754 #ifdef DETECTIONOUTPUT_FREEMOTION
00755     detection->freePoint[1] = P;
00756     detection->freePoint[0] = Q;
00757 #endif
00758     detection->normal=-t2.n();
00759     detection->value = PQ.norm();
00760     detection->value -= contactDist;
00761     return 1;
00762 }
00763 */
00764 void MinProximityIntersection::draw()
00765 {
00766     if (!getContext()->getShowCollisionModels())
00767         return;
00768 }
00769 
00770 
00771 } // namespace collision
00772 
00773 } // namespace component
00774 
00775 } // namespace sofa
00776 

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