edge_collide.cpp

Go to the documentation of this file.
00001 
00005 /* Copyright, 2001 Nevrax Ltd.
00006  *
00007  * This file is part of NEVRAX NEL.
00008  * NEVRAX NEL is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2, or (at your option)
00011  * any later version.
00012 
00013  * NEVRAX NEL is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * General Public License for more details.
00017 
00018  * You should have received a copy of the GNU General Public License
00019  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00020  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00021  * MA 02111-1307, USA.
00022  */
00023 
00024 #include "stdpacs.h"
00025 
00026 #include "edge_collide.h"
00027 
00028 using namespace NLMISC;
00029 using namespace std;
00030 
00031 
00032 
00033 namespace NLPACS
00034 {
00035 
00036 
00037 static  const   float   EdgeCollideEpsilon= 1e-5f;
00038 
00039 
00040 // ***************************************************************************
00041 void        CEdgeCollide::make(const CVector2f &p0, const CVector2f &p1)
00042 {
00043     P0= p0;
00044     P1= p1;
00045     // translation axis of the edge.
00046     Dir= P1-P0;
00047     Dir.normalize();
00048     A0= P0*Dir;
00049     A1= P1*Dir;
00050     // line equation.
00051     Norm.x=  Dir.y;
00052     Norm.y= -Dir.x;
00053     C= - P0*Norm;
00054 }
00055 
00056 
00057 // ***************************************************************************
00058 CRational64 CEdgeCollide::testPointMove(const CVector2f &start, const CVector2f &end, TPointMoveProblem &moveBug)
00059 {
00060     /*
00061         To have a correct test (with no float precision problem):
00062             - test first if there is collision beetween the 2 edges:
00063                 - test if first edge collide the other line.
00064                 - test if second edge collide the other line.
00065                 - if both true, yes, there is a collision.
00066             - compute time of collision.
00067     */
00068 
00069 
00070     // *this must be a correct edge.
00071     if(P0==P1)
00072     {
00073         moveBug= EdgeNull;
00074         return -1;
00075     }
00076 
00077     // if no movement, no collision.
00078     if(start==end)
00079         return 1;
00080 
00081     // NB those edges are snapped (1/256 for edgeCollide, and 1/1024 for start/end), so no float problem here.
00082     // precision is 20 bits.
00083     CVector2f   normEdge;
00084     CVector2f   normMove;
00085     CVector2f   deltaEdge;
00086     CVector2f   deltaMove;
00087 
00088     // compute normal of the edge (not normalized, because no need, and for precision problem).
00089     deltaEdge= P1-P0;
00090     normEdge.x= -deltaEdge.y;
00091     normEdge.y= deltaEdge.x;
00092 
00093     // compute normal of the movement (not normalized, because no need, and for precision problem).
00094     deltaMove= end-start;
00095     normMove.x= -deltaMove.y;
00096     normMove.y= deltaMove.x;
00097 
00098     // distance from points of movment against edge line. Use double, because of multiplication.
00099     // precision is now 43 bits.
00100     double  moveD0= (double)normEdge.x*(double)(start.x-P0.x) + (double)normEdge.y*(double)(start.y-P0.y);
00101     double  moveD1= (double)normEdge.x*(double)(end.x  -P0.x) + (double)normEdge.y*(double)(end.y  -P0.y);
00102 
00103     // distance from points of edge against movement line. Use double, because of multiplication.
00104     // precision is now 43 bits.
00105     double  edgeD0= (double)normMove.x*(double)(P0.x-start.x) + (double)normMove.y*(double)(P0.y-start.y);
00106     double  edgeD1= (double)normMove.x*(double)(P1.x-start.x) + (double)normMove.y*(double)(P1.y-start.y);
00107 
00108 
00109     // If both edges intersect lines (including endpoints), there is a collision, else none.
00110     sint    sgnMove0, sgnMove1;
00111     sgnMove0= fsgn(moveD0);
00112     sgnMove1= fsgn(moveD1);
00113 
00114     // special case if the 2 edges lies on the same line.
00115     if(sgnMove0==0 && sgnMove1==0)
00116     {
00117         // must test if there is a collision. if yes, problem.
00118         // project all the points on the line of the edge.
00119         // Use double because of multiplication. precision is now 43 bits.
00120         double  moveA0= (double)deltaEdge.x*(double)(start.x-P0.x) + (double)deltaEdge.y*(double)(start.y-P0.y);
00121         double  moveA1= (double)deltaEdge.x*(double)(end.x  -P0.x) + (double)deltaEdge.y*(double)(end.y  -P0.y);
00122         double  edgeA0= 0;
00123         double  edgeA1= (double)deltaEdge.x*(double)deltaEdge.x + (double)deltaEdge.y*(double)deltaEdge.y;
00124 
00125         // Test is there is intersection (endpoints included). if yes, return -1. else return 1 (no collision at all).
00126         if(moveA1>=edgeA0 && edgeA1>=moveA0)
00127         {
00128             moveBug= ParallelEdges;
00129             return -1;
00130         }
00131         else
00132             return 1;
00133     }
00134 
00135     // if on same side of the line=> there is no collision.
00136     if( sgnMove0==sgnMove1)
00137         return 1;
00138 
00139     // test edge against move line.
00140     sint    sgnEdge0, sgnEdge1;
00141     sgnEdge0= fsgn(edgeD0);
00142     sgnEdge1= fsgn(edgeD1);
00143 
00144     // should not have this case, because tested before with (sgnMove==0 && sgnMove1==0).
00145     nlassert(sgnEdge0!=0 || sgnEdge1!=0);
00146 
00147 
00148     // if on same side of the line, no collision against this edge.
00149     if( sgnEdge0==sgnEdge1 )
00150         return 1;
00151 
00152     // Here the edges intersect, but ensure that there is no limit problem.
00153     if(sgnEdge0==0 || sgnEdge1==0)
00154     {
00155         moveBug= TraverseEndPoint;
00156         return -1;
00157     }
00158     else if(sgnMove1==0)
00159     {
00160         moveBug= StopOnEdge;
00161         return -1;
00162     }
00163     else if(sgnMove0==0)
00164     {
00165         // this should not arrive.
00166         moveBug= StartOnEdge;
00167         return -1;
00168     }
00169 
00170 
00171     // Here, there is a normal collision, just compute it.
00172     // Because of Division, there is a precision lost in double. So compute a CRational64.
00173     // First, compute numerator and denominator in the highest precision. this is 1024*1024 because of prec multiplication.
00174     double      numerator= (0-moveD0)*1024*1024;
00175     double      denominator= (moveD1-moveD0)*1024*1024;
00176     sint64      numeratorInt= (sint64)numerator;
00177     sint64      denominatorInt= (sint64)denominator;
00178 /*
00179     nlassert(numerator == numeratorInt);
00180     nlassert(denominator == denominatorInt);
00181 */
00182 /*
00183     if (numerator != numeratorInt)
00184         nlwarning("numerator(%f) != numeratorInt(%"NL_I64"d)", numerator, numeratorInt);
00185     if (denominator != denominatorInt)
00186         nlwarning("denominator(%f) != denominatorInt(%"NL_I64"d)", denominator, denominatorInt);
00187 */
00188     return CRational64(numeratorInt, denominatorInt);
00189 }
00190 
00191 
00192 // ***************************************************************************
00193 static  inline float        testCirclePoint(const CVector2f &start, const CVector2f &delta, float radius, const CVector2f &point)
00194 {
00195     // factors of the qaudratic: at² + bt + c=0
00196     float       a,b,c;
00197     float       dta;
00198     float       r0, r1, res;
00199     CVector2f   relC, relV;
00200 
00201     // As long as delta is not NULL (ensured in testCircleMove() ), this code should not generate Divide by 0.
00202 
00203     // compute quadratic..
00204     relC= start-point;
00205     relV= delta;
00206     a= relV.x*relV.x + relV.y*relV.y;
00207     // a should be >0. BUT BECAUSE OF PRECISION PROBLEM, it may be ==0, and then cause
00208     // divide by zero (because b may be near 0, but not 0)
00209     if(a==0)
00210     {
00211         // in this case the move is very small. return 0 if the point is in the circle and if we go toward the point
00212         if(relC.norm()<radius && relC*delta<0)
00213             return 0;
00214         else
00215             return 1;
00216     }
00217     else
00218     {
00219         b= 2* (relC.x*relV.x + relC.y*relV.y);
00220         c= relC.x*relC.x + relC.y*relC.y - radius*radius;
00221         // compute delta of the quadratic.
00222         dta= b*b - 4*a*c;   // b²-4ac
00223         if(dta>=0)
00224         {
00225             dta= (float)sqrt(dta);
00226             r0= (-b -dta)/(2*a);
00227             r1= (-b +dta)/(2*a);
00228             // since a>0, r0<=r1.
00229             if(r0>r1)
00230                 swap(r0,r1);
00231             // if r1 is negative, then we are out and go away from this point. OK.
00232             if(r1<=0)
00233             {
00234                 res= 1;
00235             }
00236             // if r0 is positive, then we may collide this point.
00237             else if(r0>=0)
00238             {
00239                 res= min(1.f, r0);
00240             }
00241             else    // r0<0 && r1>0. the point is already in the sphere!!
00242             {
00243                 //nlinfo("COL: Point problem: %.2f, %.2f.  b=%.2f", r0, r1, b);
00244                 // we allow the movement only if we go away from this point.
00245                 // this is true if the derivative at t=0 is >=0 (because a>0).
00246                 if(b>0)
00247                     res= 1; // go out.
00248                 else
00249                     res=0;
00250             }
00251         }
00252         else
00253         {
00254             // never hit this point along this movement.
00255             res= 1;
00256         }
00257     }
00258 
00259     return res;
00260 }
00261 
00262 
00263 // ***************************************************************************
00264 float       CEdgeCollide::testCircleMove(const CVector2f &start, const CVector2f &delta, float radius, CVector2f &normal)
00265 {
00266     // If the movement is NULL, return 1 (no collision!)
00267     if( delta.isNull() )
00268         return 1;
00269 
00270     // distance from point to line.
00271     double  dist= start*Norm + C;
00272     // projection of speed on normal.
00273     double  speed= delta*Norm;
00274 
00275     // test if the movement is against the line or not.
00276     bool    sensPos= dist>0;
00277     bool    sensSpeed= speed>0;
00278 
00279     // Does the point intersect the line?
00280     dist= fabs(dist) - radius;
00281     speed= fabs(speed);
00282     if( dist > speed )
00283         return 1;
00284 
00285     // if not already in collision with the line, test when it collides.
00286     // ===============================
00287     if(dist>=0)
00288     {
00289         // if signs are equals, same side of the line, so we allow the circle to leave the line.
00290         if(sensPos==sensSpeed )
00291             return 1;
00292 
00293         // if speed is 0, it means that movement is parralel to the line => never collide.
00294         if(speed==0)
00295             return 1;
00296 
00297         // collide the line, at what time.
00298         double  t= dist/speed;
00299 
00300 
00301         // compute the collision position of the Circle on the edge.
00302         // this gives the center of the sphere at the collision point.
00303         CVector2d   proj= CVector2d(start) + CVector2d(delta)*t;
00304         // must add radius vector.
00305         proj+= Norm * (sensSpeed?radius:-radius);
00306         // compute projection on edge.
00307         double      aProj= proj*Dir;
00308 
00309         // if on the interval of the edge.
00310         if( aProj>=A0 && aProj<=A1)
00311         {
00312             // collision occurs on interior of the edge. the normal to return is +- Norm.
00313             if(sensPos) // if algebric distance of start position was >0.
00314                 normal= Norm;
00315             else
00316                 normal= -Norm;
00317 
00318             // return time of collision.
00319             return (float)t;
00320         }
00321     }
00322     // else, must test if circle collide segment at t=0. if yes, return 0.
00323     // ===============================
00324     else
00325     {
00326         // There is just need to test if projection of circle's center onto the line hit the segment.
00327         // This is not a good test to know if a circle intersect a segment, but other cases are
00328         // managed with test of endPoints of the segment after.
00329         float       aProj= start*Dir;
00330 
00331         // if on the interval of the edge.
00332         if( aProj>=A0 && aProj<=A1)
00333         {
00334             // if signs are equals, same side of the line, so we allow the circle to leave the edge.
00335             /* Special case: do not allow to leave the edge if we are too much in the edge.
00336              It is important for CGlobalRetriever::testCollisionWithCollisionChains() because of the
00337              "SURFACEMOVE NOT DETECTED" Problem.
00338              Suppose we can walk on this chain SA/SB (separate Surface A/SurfaceB). Suppose we are near this edge,
00339              and on Surface SA, and suppose there is an other chain SB/SC the circle collide with. If we
00340              return 1 (no collision), SB/SC won't be detected (because only SA/?? chains will be tested) and
00341              so the cylinder will penetrate SB/SC...
00342              This case arise at best if chains SA/SB and chain SB/SC do an angle of 45deg
00343             */
00344             if(sensPos==sensSpeed && (-dist)<0.5*radius)
00345             {
00346                 return 1;
00347             }
00348             else
00349             {
00350                 // hit the interior of the edge, and sensPos!=sensSpeed. So must stop now!!
00351                 // collision occurs on interior of the edge. the normal to return is +- Norm.
00352                 if(sensPos) // if algebric distance of start position was >0.
00353                     normal= Norm;
00354                 else
00355                     normal= -Norm;
00356 
00357                 return 0;
00358             }
00359         }
00360     }
00361 
00362     // In this case, the Circle do not hit the edge on the interior, but may hit on borders.
00363     // ===============================
00364     // Then, we must compute collision sphere-points.
00365     float       tmin, ttmp;
00366     // first point.
00367     tmin= testCirclePoint(start, delta, radius, P0);
00368     // second point.
00369     ttmp= testCirclePoint(start, delta, radius, P1);
00370     tmin= min(tmin, ttmp);
00371 
00372     // if collision occurs, compute normal of collision.
00373     if(tmin<1)
00374     {
00375         // to which point we collide?
00376         CVector2f   colPoint= tmin==ttmp? P1 : P0;
00377         // compute position of the entity at collision.
00378         CVector2f   colPos= start + delta*tmin;
00379 
00380         // and so we have this normal (the perpendicular of the tangent at this point).
00381         normal= colPos - colPoint;
00382         normal.normalize();
00383     }
00384 
00385     return tmin;
00386 }
00387 
00388 
00389 
00390 // ***************************************************************************
00391 bool        CEdgeCollide::testEdgeMove(const CVector2f &q0, const CVector2f &q1, const CVector2f &delta, float &tMin, float &tMax, bool &normalOnBox)
00392 {
00393     double  a,b,cv,cc,  d,e,f;
00394     CVector2d   tmp;
00395 
00396     // compute D1 line equation of q0q1. bx - ay + c(t)=0, where c is function of time [0,1].
00397     // ===========================
00398     tmp= q1 - q0;       // NB: along time, the direction doesn't change.
00399     // Divide by norm()², so that  a projection on this edge is true if the proj is in interval [0,1].
00400     tmp/= tmp.sqrnorm();
00401     a= tmp.x;
00402     b= tmp.y;
00403     // c= - q0(t)*CVector2d(b,-a).  but since q0(t) is a function of time t (q0+delta*t), compute cv, and cc.
00404     // so c= cv*t + cc.
00405     cv= - CVector2d(b,-a)*delta;
00406     cc= - CVector2d(b,-a)*q0;
00407 
00408     // compute D2 line equation of P0P1. ex - dy + f=0.
00409     // ===========================
00410     tmp= P1 - P0;
00411     // Divide by norm()², so that  a projection on this edge is true if the proj is in interval [0,1].
00412     tmp/= tmp.sqrnorm();
00413     d= tmp.x;
00414     e= tmp.y;
00415     f= - CVector2d(e,-d)*P0;
00416 
00417 
00418     // Solve system.
00419     // ===========================
00420     /*
00421         Compute the intersection I of 2 lines across time.
00422         We have the system:
00423             bx - ay + c(t)=0
00424             ex - dy + f=0
00425 
00426         which solve for:
00427             det= ae-bd  (0 <=> // lines)
00428             x(t)= (d*c(t) - fa) / det
00429             y(t)= (e*c(t) - fb) / det
00430     */
00431 
00432     // determinant of matrix2x2.
00433     double  det= a*e - b*d;
00434     // if to near of 0. (take delta for reference of test).
00435     if(det==0 || fabs(det)<delta.norm()*EdgeCollideEpsilon)
00436         return false;
00437 
00438     // intersection I(t)= pInt + vInt*t.
00439     CVector2d       pInt, vInt;
00440     pInt.x= ( d*cc - f*a ) / det;
00441     pInt.y= ( e*cc - f*b ) / det;
00442     vInt.x= ( d*cv ) / det;
00443     vInt.y= ( e*cv ) / det;
00444 
00445 
00446     // Project Intersection.
00447     // ===========================
00448     /*
00449         Now, we project x,y onto each line D1 and D2, which gives  u(t) and v(t), each one giving the parameter of
00450         the parametric line function. When it is in [0,1], we are on the edge.
00451 
00452         u(t)= (I(t)-q0(t)) * CVector2d(a,b) = uc + uv*t
00453         v(t)= (I(t)-P0) * CVector2d(d,e)    = vc + vv*t
00454     */
00455     double  uc, uv;
00456     double  vc, vv;
00457     // NB: q0(t)= q0+delta*t
00458     uc= (pInt-q0) * CVector2d(a,b);
00459     uv= (vInt-delta) * CVector2d(a,b);
00460     vc= (pInt-P0) * CVector2d(d,e);
00461     vv= (vInt) * CVector2d(d,e);
00462 
00463 
00464     // Compute intervals.
00465     // ===========================
00466     /*
00467         Now, for each edge, compute time interval where parameter is in [0,1]. If intervals overlap, there is a collision.
00468     */
00469     double  tu0, tu1, tv0, tv1;
00470     // infinite interval.
00471     bool    allU=false, allV=false;
00472 
00473     // compute time interval for u(t).
00474     if(uv==0 || fabs(uv)<EdgeCollideEpsilon)
00475     {
00476         // The intersection does not move along D1. Always projected on u(t)=uc. so if in [0,1], OK, else never collide.
00477         if(uc<0 || uc>1)
00478             return false;
00479         // else suppose "always valid".
00480         tu0 =tu1= 0;
00481         allU= true;
00482     }
00483     else
00484     {
00485         tu0= (0-uc)/uv; // t for u(t)=0
00486         tu1= (1-uc)/uv; // t for u(t)=1
00487     }
00488 
00489     // compute time interval for v(t).
00490     if(vv==0 || fabs(vv)<EdgeCollideEpsilon)
00491     {
00492         // The intersection does not move along D2. Always projected on v(t)=vc. so if in [0,1], OK, else never collide.
00493         if(vc<0 || vc>1)
00494             return false;
00495         // else suppose "always valid".
00496         tv0 =tv1= 0;
00497         allV= true;
00498     }
00499     else
00500     {
00501         tv0= (0-vc)/vv; // t for v(t)=0
00502         tv1= (1-vc)/vv; // t for v(t)=1
00503     }
00504 
00505 
00506     // clip intervals.
00507     // ===========================
00508     // order time interval.
00509     if(tu0>tu1)
00510         swap(tu0, tu1);     // now, [tu0, tu1] represent the time interval where line D2 hit the edge D1.
00511     if(tv0>tv1)
00512         swap(tv0, tv1);     // now, [tv0, tv1] represent the time interval where line D1 hit the edge D2.
00513 
00514     normalOnBox= false;
00515     if(!allU && !allV)
00516     {
00517         // if intervals do not overlap, no collision.
00518         if(tu0>tv1 || tv0>tu1)
00519             return false;
00520         else
00521         {
00522             // compute intersection of intervals.
00523             tMin= (float)max(tu0, tv0);
00524             tMax= (float)min(tu1, tv1);
00525             // if collision of edgeCollide against the bbox.
00526             if(tv0>tu0)
00527                 normalOnBox= true;
00528         }
00529     }
00530     else if(allU)
00531     {
00532         // intersection of Infinite and V interval.
00533         tMin= (float)tv0;
00534         tMax= (float)tv1;
00535         // if collision of edgeCollide against the bbox.
00536         normalOnBox= true;
00537     }
00538     else if(allV)
00539     {
00540         // intersection of Infinite and U interval.
00541         tMin= (float)tu0;
00542         tMax= (float)tu1;
00543     }
00544     else
00545     {
00546         // if allU && allV, this means delta is near 0, and so there is always collision.
00547         tMin= -1000;
00548         tMax= 1000;
00549     }
00550 
00551     return true;
00552 }
00553 
00554 
00555 // ***************************************************************************
00556 float       CEdgeCollide::testBBoxMove(const CVector2f &start, const CVector2f &delta, const CVector2f bbox[4], CVector2f &normal)
00557 {
00558     // distance from center to line.
00559     float   dist= start*Norm + C;
00560 
00561     // test if the movement is against the line or not.
00562     bool    sensPos= dist>0;
00563     // if signs are equals, same side of the line, so we allow the circle to leave the line.
00564     /*if(sensPos==sensSpeed)
00565         return 1;*/
00566 
00567 
00568     // Else, do 4 test edge/edge, and return Tmin.
00569     float   tMin = 0.f, tMax = 0.f;
00570     bool    edgeCollided= false;
00571     bool    normalOnBox= false;
00572     CVector2f   boxNormal(0.f, 0.f);
00573     for(sint i=0;i<4;i++)
00574     {
00575         float   t0, t1;
00576         bool    nob;
00577         CVector2f   a= bbox[i];
00578         CVector2f   b= bbox[(i+1)&3];
00579 
00580         // test move against this edge.
00581         if(testEdgeMove(a, b, delta, t0, t1, nob))
00582         {
00583             if(edgeCollided)
00584             {
00585                 tMin= min(t0, tMin);
00586                 tMax= max(t1, tMax);
00587             }
00588             else
00589             {
00590                 edgeCollided= true;
00591                 tMin= t0;
00592                 tMax= t1;
00593             }
00594 
00595             // get normal of box against we collide.
00596             if(tMin==t0)
00597             {
00598                 normalOnBox= nob;
00599                 if(nob)
00600                 {
00601                     CVector2f   dab;
00602                     // bbox must be CCW.
00603                     dab= b-a;
00604                     // the normal is computed so that the vector goes In the bbox.
00605                     boxNormal.x= -dab.y;
00606                     boxNormal.y= dab.x;
00607                 }
00608             }
00609         }
00610     }
00611 
00612     // if collision occurs,and int the [0,1] interval...
00613     if(edgeCollided && tMin<1 && tMax>0)
00614     {
00615         // compute normal of collision.
00616         if(normalOnBox)
00617         {
00618             // assume collsion is an endpoint of the edge against the bbox.
00619             normal= boxNormal;
00620         }
00621         else
00622         {
00623             // assume collision occurs on interior of the edge. the normal to return is +- Norm.
00624             if(sensPos) // if algebric distance of start position was >0.
00625                 normal= Norm;
00626             else
00627                 normal= -Norm;
00628         }
00629 
00630         // compute time of collison.
00631         if(tMin>0)
00632             // return time of collision.
00633             return tMin;
00634         else
00635         {
00636             // The bbox is inside the edge, at t==0. test if it goes out or not.
00637             // accept only if we are much near the exit than the enter.
00638             /* NB: 0.2 is an empirical value "which works well". Normally, 1 is the good value, but because of the
00639                 "SURFACEMOVE NOT DETECTED" Problem (see testCircleMove()), we must be more restrictive.
00640             */
00641             if( tMax<0.2*(-tMin) )
00642                 return 1;
00643             else
00644                 return 0;
00645         }
00646     }
00647     else
00648         return 1;
00649 
00650 }
00651 
00652 
00653 // ***************************************************************************
00654 bool        CEdgeCollide::testBBoxCollide(const CVector2f bbox[4])
00655 {
00656     // clip the edge against the edge of the bbox.
00657     CVector2f       p0= P0, p1= P1;
00658 
00659     for(sint i=0; i<4; i++)
00660     {
00661         CVector2f   a= bbox[i];
00662         CVector2f   b= bbox[(i+1)&3];
00663         CVector2f   delta= b-a, norm;
00664         // sign is important. bbox is CCW. normal goes OUT the bbox.
00665         norm.x= delta.y;
00666         norm.y= -delta.x;
00667 
00668         float   d0= (p0-a)*norm;
00669         float   d1= (p1-a)*norm;
00670 
00671         // if boths points are out this plane, no collision.
00672         if( d0>0 && d1>0)
00673             return false;
00674         // if difference, must clip.
00675         if( d0>0 || d1>0)
00676         {
00677             CVector2f   intersect= p0 + (p1-p0)* ((0-d0)/(d1-d0));
00678             if(d1>0)
00679                 p1= intersect;
00680             else
00681                 p0= intersect;
00682         }
00683     }
00684 
00685     // if a segment is still in the bbox, collision occurs.
00686     return true;
00687 }
00688 
00689 
00690 
00691 } // NLPACS

Generated on Thu Jan 7 08:26:36 2010 for NeL by  doxygen 1.6.1