NLPACS::CEdgeCollide Class Reference

#include <edge_collide.h>

Inheritance diagram for NLPACS::CEdgeCollide:

NLPACS::CEdgeCollideNode

Detailed Description

Collisions against edge in 2D.
Author:
Lionel Berenguier

Nevrax France

Date:
2001

Definition at line 180 of file edge_collide.h.

Public Types

enum  TPointMoveProblem {
  ParallelEdges = 0, StartOnEdge, StopOnEdge, TraverseEndPoint,
  EdgeNull, PointMoveProblemCount
}

Public Member Functions

void make (const CVector2f &p0, const CVector2f &p1)
bool testBBoxCollide (const CVector2f bbox[4])
float testBBoxMove (const CVector2f &start, const CVector2f &delta, const CVector2f bbox[4], CVector2f &normal)
float testCircleMove (const CVector2f &start, const CVector2f &delta, float radius, CVector2f &normal)
CRational64 testPointMove (const CVector2f &start, const CVector2f &end, TPointMoveProblem &moveBug)

Data Fields

float A0
float A1
float C
CVector2f Dir
CVector2f Norm
CVector2f P0
CVector2f P1

Private Member Functions

bool testEdgeMove (const CVector2f &q0, const CVector2f &q1, const CVector2f &delta, float &tMin, float &tMax, bool &normalOnBox)


Member Enumeration Documentation

enum NLPACS::CEdgeCollide::TPointMoveProblem
 

Enumeration values:
ParallelEdges 
StartOnEdge 
StopOnEdge 
TraverseEndPoint 
EdgeNull 
PointMoveProblemCount 

Definition at line 183 of file edge_collide.h.


Member Function Documentation

void NLPACS::CEdgeCollide::make const CVector2f p0,
const CVector2f p1
 

Definition at line 43 of file edge_collide.cpp.

References A0, A1, C, Norm, NLMISC::CVector2f::normalize(), NLMISC::CVector2f::x, and NLMISC::CVector2f::y.

Referenced by NLPACS::CLocalRetriever::testCollision(), and NLPACS::CRetrieverInstance::testExteriorCollision().

00044 {
00045         P0= p0;
00046         P1= p1;
00047         // translation axis of the edge.
00048         Dir= P1-P0;
00049         Dir.normalize();
00050         A0= P0*Dir;
00051         A1= P1*Dir;
00052         // line equation.
00053         Norm.x=  Dir.y;
00054         Norm.y= -Dir.x;
00055         C= - P0*Norm;
00056 }

bool NLPACS::CEdgeCollide::testBBoxCollide const CVector2f  bbox[4]  ) 
 

return true if this oriented bbox collide this edge.

Parameters:
bbox 4 points of the bbox, in CCW.
Returns:
true if collision occurs.

Definition at line 657 of file edge_collide.cpp.

References sint, NLMISC::CVector2f::x, and NLMISC::CVector2f::y.

Referenced by NLPACS::CGlobalRetriever::testRotCollisionWithCollisionChains().

00658 {
00659         // clip the edge against the edge of the bbox.
00660         CVector2f               p0= P0, p1= P1;
00661 
00662         for(sint i=0; i<4; i++)
00663         {
00664                 CVector2f       a= bbox[i];
00665                 CVector2f       b= bbox[(i+1)&3];
00666                 CVector2f       delta= b-a, norm;
00667                 // sign is important. bbox is CCW. normal goes OUT the bbox.
00668                 norm.x= delta.y;
00669                 norm.y= -delta.x;
00670 
00671                 float   d0= (p0-a)*norm;
00672                 float   d1= (p1-a)*norm;
00673 
00674                 // if boths points are out this plane, no collision.
00675                 if( d0>0 && d1>0)
00676                         return false;
00677                 // if difference, must clip.
00678                 if( d0>0 || d1>0)
00679                 {
00680                         CVector2f       intersect= p0 + (p1-p0)* ((0-d0)/(d1-d0));
00681                         if(d1>0)
00682                                 p1= intersect;
00683                         else
00684                                 p0= intersect;
00685                 }
00686         }
00687 
00688         // if a segment is still in the bbox, collision occurs.
00689         return true;
00690 }

float NLPACS::CEdgeCollide::testBBoxMove const CVector2f start,
const CVector2f delta,
const CVector2f  bbox[4],
CVector2f normal
 

return 1 either if the bbox moves away from the line, or no collision occurs. Else return a [0,1[ interval. If collision occurs (ie return<1), return in "normal" the normal of the collision. It may be normal of edge (+-), or normal against a point of the edge.

Parameters:
bbox 4 points of the bbox at start. start must be the barycentre of those points.

Definition at line 559 of file edge_collide.cpp.

References C, min, Norm, sint, testEdgeMove(), NLMISC::CVector2f::x, and NLMISC::CVector2f::y.

Referenced by NLPACS::CGlobalRetriever::testCollisionWithCollisionChains().

00560 {
00561         // distance from center to line.
00562         float   dist= start*Norm + C;
00563 
00564         // test if the movement is against the line or not.
00565         bool    sensPos= dist>0;
00566         // if signs are equals, same side of the line, so we allow the circle to leave the line.
00567         /*if(sensPos==sensSpeed)
00568                 return 1;*/
00569 
00570 
00571         // Else, do 4 test edge/edge, and return Tmin.
00572         float   tMin, tMax;
00573         bool    edgeCollided= false;
00574         bool    normalOnBox= false;
00575         CVector2f       boxNormal;
00576         for(sint i=0;i<4;i++)
00577         {
00578                 float   t0, t1;
00579                 bool    nob;
00580                 CVector2f       a= bbox[i];
00581                 CVector2f       b= bbox[(i+1)&3];
00582 
00583                 // test move against this edge.
00584                 if(testEdgeMove(a, b, delta, t0, t1, nob))
00585                 {
00586                         if(edgeCollided)
00587                         {
00588                                 tMin= min(t0, tMin);
00589                                 tMax= max(t1, tMax);
00590                         }
00591                         else
00592                         {
00593                                 edgeCollided= true;
00594                                 tMin= t0;
00595                                 tMax= t1;
00596                         }
00597 
00598                         // get normal of box against we collide.
00599                         if(tMin==t0)
00600                         {
00601                                 normalOnBox= nob;
00602                                 if(nob)
00603                                 {
00604                                         CVector2f       dab;
00605                                         // bbox must be CCW.
00606                                         dab= b-a;
00607                                         // the normal is computed so that the vector goes In the bbox.
00608                                         boxNormal.x= -dab.y;
00609                                         boxNormal.y= dab.x;
00610                                 }
00611                         }
00612                 }
00613         }
00614 
00615         // if collision occurs,and int the [0,1] interval...
00616         if(edgeCollided && tMin<1 && tMax>0)
00617         {
00618                 // compute normal of collision.
00619                 if(normalOnBox)
00620                 {
00621                         // assume collsion is an endpoint of the edge against the bbox.
00622                         normal= boxNormal;
00623                 }
00624                 else
00625                 {
00626                         // assume collision occurs on interior of the edge. the normal to return is +- Norm.
00627                         if(sensPos)     // if algebric distance of start position was >0.
00628                                 normal= Norm;
00629                         else
00630                                 normal= -Norm;
00631                 }
00632 
00633                 // compute time of collison.
00634                 if(tMin>0)
00635                         // return time of collision.
00636                         return tMin;
00637                 else
00638                 {
00639                         // The bbox is inside the edge, at t==0. test if it goes out or not.
00640                         // accept only if we are much near the exit than the enter.
00641                         /* NB: 0.2 is an empirical value "which works well". Normally, 1 is the good value, but because of the
00642                                 "SURFACEMOVE NOT DETECTED" Problem (see testCircleMove()), we must be more restrictive.
00643                         */
00644                         if( tMax<0.2*(-tMin) )
00645                                 return 1;
00646                         else
00647                                 return 0;
00648                 }
00649         }
00650         else
00651                 return 1;
00652 
00653 }

float NLPACS::CEdgeCollide::testCircleMove const CVector2f start,
const CVector2f delta,
float  radius,
CVector2f normal
 

return 1 either if the circle moves away from the line, or no collision occurs. Else return a [0,1[ interval. If collision occurs (ie return<1), return in "normal" the normal of the collision. It may be normal of edge (+-), or normal against a point of the edge.

Definition at line 265 of file edge_collide.cpp.

References A0, A1, C, NLMISC::CVector2f::isNull(), min, Norm, NLMISC::CVector2f::normalize(), t, and NLPACS::testCirclePoint().

Referenced by NLPACS::CGlobalRetriever::testCollisionWithCollisionChains().

00266 {
00267         // If the movement is NULL, return 1 (no collision!)
00268         if(     delta.isNull() )
00269                 return 1;
00270 
00271         // distance from point to line.
00272         double  dist= start*Norm + C;
00273         // projection of speed on normal.
00274         double  speed= delta*Norm;
00275 
00276         // test if the movement is against the line or not.
00277         bool    sensPos= dist>0;
00278         bool    sensSpeed= speed>0;
00279 
00280         // Does the point intersect the line?
00281         dist= fabs(dist) - radius;
00282         speed= fabs(speed);
00283         if( dist > speed )
00284                 return 1;
00285 
00286         // if not already in collision with the line, test when it collides.
00287         // ===============================
00288         if(dist>=0)
00289         {
00290                 // if signs are equals, same side of the line, so we allow the circle to leave the line.
00291                 if(sensPos==sensSpeed )
00292                         return 1;
00293 
00294                 // if speed is 0, it means that movement is parralel to the line => never collide.
00295                 if(speed==0)
00296                         return 1;
00297 
00298                 // collide the line, at what time.
00299                 double  t= dist/speed;
00300 
00301 
00302                 // compute the collision position of the Circle on the edge.
00303                 // this gives the center of the sphere at the collision point.
00304                 CVector2d       proj= CVector2d(start) + CVector2d(delta)*t;
00305                 // must add radius vector.
00306                 proj+= Norm * (sensSpeed?radius:-radius);
00307                 // compute projection on edge.
00308                 double          aProj= proj*Dir;
00309 
00310                 // if on the interval of the edge.
00311                 if( aProj>=A0 && aProj<=A1)
00312                 {
00313                         // collision occurs on interior of the edge. the normal to return is +- Norm.
00314                         if(sensPos)     // if algebric distance of start position was >0.
00315                                 normal= Norm;
00316                         else
00317                                 normal= -Norm;
00318 
00319                         // return time of collision.
00320                         return (float)t;
00321                 }
00322         }
00323         // else, must test if circle collide segment at t=0. if yes, return 0.
00324         // ===============================
00325         else
00326         {
00327                 // There is just need to test if projection of circle's center onto the line hit the segment.
00328                 // This is not a good test to know if a circle intersect a segment, but other cases are
00329                 // managed with test of endPoints of the segment after.
00330                 float           aProj= start*Dir;
00331 
00332                 // if on the interval of the edge.
00333                 if( aProj>=A0 && aProj<=A1)
00334                 {
00335                         // if signs are equals, same side of the line, so we allow the circle to leave the edge.
00336                         /* Special case: do not allow to leave the edge if we are too much in the edge.
00337                          It is important for CGlobalRetriever::testCollisionWithCollisionChains() because of the
00338                          "SURFACEMOVE NOT DETECTED" Problem.
00339                          Suppose we can walk on this chain SA/SB (separate Surface A/SurfaceB). Suppose we are near this edge, 
00340                          and on Surface SA, and suppose there is an other chain SB/SC the circle collide with. If we 
00341                          return 1 (no collision), SB/SC won't be detected (because only SA/?? chains will be tested) and 
00342                          so the cylinder will penetrate SB/SC...
00343                          This case arise at best if chains SA/SB and chain SB/SC do an angle of 45deg
00344 
00345                          \todo yoyo: this is a Hack.
00346                         */
00347                         if(sensPos==sensSpeed && (-dist)<0.5*radius)
00348                         {
00349                                 return 1;
00350                         }
00351                         else
00352                         {
00353                                 // hit the interior of the edge, and sensPos!=sensSpeed. So must stop now!!
00354                                 // collision occurs on interior of the edge. the normal to return is +- Norm.
00355                                 if(sensPos)     // if algebric distance of start position was >0.
00356                                         normal= Norm;
00357                                 else
00358                                         normal= -Norm;
00359 
00360                                 return 0;
00361                         }
00362                 }
00363         }
00364 
00365         // In this case, the Circle do not hit the edge on the interior, but may hit on borders.
00366         // ===============================
00367         // Then, we must compute collision sphere-points.
00368         float           tmin, ttmp;
00369         // first point.
00370         tmin= testCirclePoint(start, delta, radius, P0);
00371         // second point.
00372         ttmp= testCirclePoint(start, delta, radius, P1);
00373         tmin= min(tmin, ttmp);
00374 
00375         // if collision occurs, compute normal of collision.
00376         if(tmin<1)
00377         {
00378                 // to which point we collide?
00379                 CVector2f       colPoint= tmin==ttmp? P1 : P0;
00380                 // compute position of the entity at collision.
00381                 CVector2f       colPos= start + delta*tmin;
00382 
00383                 // and so we have this normal (the perpendicular of the tangent at this point).
00384                 normal= colPos - colPoint;
00385                 normal.normalize();
00386         }
00387 
00388         return tmin;
00389 }

bool NLPACS::CEdgeCollide::testEdgeMove const CVector2f q0,
const CVector2f q1,
const CVector2f delta,
float &  tMin,
float &  tMax,
bool &  normalOnBox
[private]
 

test if edge collide against me. if true, return time intervals of collisions (]-oo, +oo[). NB: for simplicity, if lines are //, return false.

Definition at line 394 of file edge_collide.cpp.

References NLPACS::EdgeCollideEpsilon, min, NLMISC::CVector2f::norm(), NLMISC::CVector2d::sqrnorm(), NLMISC::CVector2d::x, and NLMISC::CVector2d::y.

Referenced by testBBoxMove().

00395 {
00396         double  a,b,cv,cc,  d,e,f;
00397         CVector2d       tmp;
00398 
00399         // compute D1 line equation of q0q1. bx - ay + c(t)=0, where c is function of time [0,1].
00400         // ===========================
00401         tmp= q1 - q0;           // NB: along time, the direction doesn't change.
00402         // Divide by norm()², so that  a projection on this edge is true if the proj is in interval [0,1].
00403         tmp/= tmp.sqrnorm();
00404         a= tmp.x;
00405         b= tmp.y;
00406         // c= - q0(t)*CVector2d(b,-a).  but since q0(t) is a function of time t (q0+delta*t), compute cv, and cc.
00407         // so c= cv*t + cc.
00408         cv= - CVector2d(b,-a)*delta;
00409         cc= - CVector2d(b,-a)*q0;
00410 
00411         // compute D2 line equation of P0P1. ex - dy + f=0.
00412         // ===========================
00413         tmp= P1 - P0;
00414         // Divide by norm()², so that  a projection on this edge is true if the proj is in interval [0,1].
00415         tmp/= tmp.sqrnorm();
00416         d= tmp.x;
00417         e= tmp.y;
00418         f= - CVector2d(e,-d)*P0;
00419 
00420 
00421         // Solve system.
00422         // ===========================
00423         /*
00424                 Compute the intersection I of 2 lines across time.
00425                 We have the system:
00426                         bx - ay + c(t)=0
00427                         ex - dy + f=0
00428 
00429                 which solve for:
00430                         det= ae-bd      (0 <=> // lines)
00431                         x(t)= (d*c(t) - fa) / det
00432                         y(t)= (e*c(t) - fb) / det
00433         */
00434 
00435         // determinant of matrix2x2.
00436         double  det= a*e - b*d;
00437         // if to near of 0. (take delta for reference of test).
00438         if(det==0 || fabs(det)<delta.norm()*EdgeCollideEpsilon)
00439                 return false;
00440 
00441         // intersection I(t)= pInt + vInt*t.
00442         CVector2d               pInt, vInt;
00443         pInt.x= ( d*cc - f*a ) / det;
00444         pInt.y= ( e*cc - f*b ) / det;
00445         vInt.x= ( d*cv ) / det;
00446         vInt.y= ( e*cv ) / det;
00447 
00448 
00449         // Project Intersection.
00450         // ===========================
00451         /*
00452                 Now, we project x,y onto each line D1 and D2, which gives  u(t) and v(t), each one giving the parameter of 
00453                 the parametric line function. When it is in [0,1], we are on the edge.
00454 
00455                 u(t)= (I(t)-q0(t)) * CVector2d(a,b)     = uc + uv*t
00456                 v(t)= (I(t)-P0) * CVector2d(d,e)        = vc + vv*t
00457         */
00458         double  uc, uv;
00459         double  vc, vv;
00460         // NB: q0(t)= q0+delta*t
00461         uc= (pInt-q0) * CVector2d(a,b);
00462         uv= (vInt-delta) * CVector2d(a,b);
00463         vc= (pInt-P0) * CVector2d(d,e);
00464         vv= (vInt) * CVector2d(d,e);
00465 
00466 
00467         // Compute intervals.
00468         // ===========================
00469         /*
00470                 Now, for each edge, compute time interval where parameter is in [0,1]. If intervals overlap, there is a collision.
00471         */
00472         double  tu0, tu1, tv0, tv1;
00473         // infinite interval.
00474         bool    allU=false, allV=false;
00475 
00476         // compute time interval for u(t).
00477         if(uv==0 || fabs(uv)<EdgeCollideEpsilon)
00478         {
00479                 // The intersection does not move along D1. Always projected on u(t)=uc. so if in [0,1], OK, else never collide.
00480                 if(uc<0 || uc>1)
00481                         return false;
00482                 // else suppose "always valid".
00483                 tu0 =tu1= 0;
00484                 allU= true;
00485         }
00486         else
00487         {
00488                 tu0= (0-uc)/uv; // t for u(t)=0
00489                 tu1= (1-uc)/uv; // t for u(t)=1
00490         }
00491 
00492         // compute time interval for v(t).
00493         if(vv==0 || fabs(vv)<EdgeCollideEpsilon)
00494         {
00495                 // The intersection does not move along D2. Always projected on v(t)=vc. so if in [0,1], OK, else never collide.
00496                 if(vc<0 || vc>1)
00497                         return false;
00498                 // else suppose "always valid".
00499                 tv0 =tv1= 0;
00500                 allV= true;
00501         }
00502         else
00503         {
00504                 tv0= (0-vc)/vv; // t for v(t)=0
00505                 tv1= (1-vc)/vv; // t for v(t)=1
00506         }
00507 
00508 
00509         // clip intervals.
00510         // ===========================
00511         // order time interval.
00512         if(tu0>tu1)
00513                 swap(tu0, tu1);         // now, [tu0, tu1] represent the time interval where line D2 hit the edge D1.
00514         if(tv0>tv1)
00515                 swap(tv0, tv1);         // now, [tv0, tv1] represent the time interval where line D1 hit the edge D2.
00516 
00517         normalOnBox= false;
00518         if(!allU && !allV)
00519         {
00520                 // if intervals do not overlap, no collision.
00521                 if(tu0>tv1 || tv0>tu1)
00522                         return false;
00523                 else
00524                 {
00525                         // compute intersection of intervals.
00526                         tMin= (float)max(tu0, tv0);
00527                         tMax= (float)min(tu1, tv1);
00528                         // if collision of edgeCollide against the bbox.
00529                         if(tv0>tu0)
00530                                 normalOnBox= true;
00531                 }
00532         }
00533         else if(allU)
00534         {
00535                 // intersection of Infinite and V interval.
00536                 tMin= (float)tv0;
00537                 tMax= (float)tv1;
00538                 // if collision of edgeCollide against the bbox.
00539                 normalOnBox= true;
00540         }
00541         else if(allV)
00542         {
00543                 // intersection of Infinite and U interval.
00544                 tMin= (float)tu0;
00545                 tMax= (float)tu1;
00546         }
00547         else
00548         {
00549                 // if allU && allV, this means delta is near 0, and so there is always collision.
00550                 tMin= -1000;
00551                 tMax= 1000;
00552         }
00553         
00554         return true;
00555 }

CRational64 NLPACS::CEdgeCollide::testPointMove const CVector2f start,
const CVector2f end,
TPointMoveProblem moveBug
 

return 1 either if no collision occurs. Else return a [0,1[ interval. return -1 if precision problem (see below). This method is used by CGlobalRetriever::doMove(). UnManageables cases arise when:

  • the movement start/stop on a edge (dist==0). In this case, don't know on what surface we arrive (before or after).
  • the movement is // to the edge and collide with it. same problem than stop on an edge.
  • the movement traverse the edge on an endpoint. In this case, there is 2+ edges sharing the point, and result is undefined. On thoses cases, moveBug is filled, and -1 is returned.

Definition at line 60 of file edge_collide.cpp.

References EdgeNull, NLMISC::fsgn(), NL_I64, nlassert, nlwarning, ParallelEdges, sint, sint64, StartOnEdge, StopOnEdge, TraverseEndPoint, NLMISC::CVector2f::x, and NLMISC::CVector2f::y.

Referenced by NLPACS::CGlobalRetriever::testMovementWithCollisionChains().

00061 {
00062         /*
00063                 To have a correct test (with no float precision problem):
00064                         - test first if there is collision beetween the 2 edges:
00065                                 - test if first edge collide the other line.
00066                                 - test if second edge collide the other line.
00067                                 - if both true, yes, there is a collision.
00068                         - compute time of collision.
00069         */
00070 
00071 
00072         // *this must be a correct edge.
00073         if(P0==P1)
00074         {
00075                 moveBug= EdgeNull;
00076                 return -1;
00077         }
00078 
00079         // if no movement, no collision.
00080         if(start==end)
00081                 return 1;
00082 
00083         // NB those edges are snapped (1/256 for edgeCollide, and 1/1024 for start/end), so no float problem here.
00084         // precision is 20 bits.
00085         CVector2f       normEdge;
00086         CVector2f       normMove;
00087         CVector2f       deltaEdge;
00088         CVector2f       deltaMove;
00089 
00090         // compute normal of the edge (not normalized, because no need, and for precision problem).
00091         deltaEdge= P1-P0;
00092         normEdge.x= -deltaEdge.y;
00093         normEdge.y= deltaEdge.x;
00094 
00095         // compute normal of the movement (not normalized, because no need, and for precision problem).
00096         deltaMove= end-start;
00097         normMove.x= -deltaMove.y;
00098         normMove.y= deltaMove.x;
00099 
00100         // distance from points of movment against edge line. Use double, because of multiplication.
00101         // precision is now 43 bits.
00102         double  moveD0= (double)normEdge.x*(double)(start.x-P0.x) + (double)normEdge.y*(double)(start.y-P0.y);
00103         double  moveD1= (double)normEdge.x*(double)(end.x  -P0.x) + (double)normEdge.y*(double)(end.y  -P0.y);
00104 
00105         // distance from points of edge against movement line. Use double, because of multiplication.
00106         // precision is now 43 bits.
00107         double  edgeD0= (double)normMove.x*(double)(P0.x-start.x) + (double)normMove.y*(double)(P0.y-start.y);
00108         double  edgeD1= (double)normMove.x*(double)(P1.x-start.x) + (double)normMove.y*(double)(P1.y-start.y);
00109 
00110 
00111         // If both edges intersect lines (including endpoints), there is a collision, else none.
00112         sint    sgnMove0, sgnMove1;
00113         sgnMove0= fsgn(moveD0);
00114         sgnMove1= fsgn(moveD1);
00115 
00116         // special case if the 2 edges lies on the same line.
00117         if(sgnMove0==0 && sgnMove1==0)
00118         {
00119                 // must test if there is a collision. if yes, problem.
00120                 // project all the points on the line of the edge.
00121                 // Use double because of multiplication. precision is now 43 bits.
00122                 double  moveA0= (double)deltaEdge.x*(double)(start.x-P0.x) + (double)deltaEdge.y*(double)(start.y-P0.y);
00123                 double  moveA1= (double)deltaEdge.x*(double)(end.x  -P0.x) + (double)deltaEdge.y*(double)(end.y  -P0.y);
00124                 double  edgeA0= 0;
00125                 double  edgeA1= (double)deltaEdge.x*(double)deltaEdge.x + (double)deltaEdge.y*(double)deltaEdge.y;
00126 
00127                 // Test is there is intersection (endpoints included). if yes, return -1. else return 1 (no collision at all).
00128                 if(moveA1>=edgeA0 && edgeA1>=moveA0)
00129                 {
00130                         moveBug= ParallelEdges;
00131                         return -1;
00132                 }
00133                 else
00134                         return 1;
00135         }
00136 
00137         // if on same side of the line=> there is no collision.
00138         if( sgnMove0==sgnMove1)
00139                 return 1;
00140 
00141         // test edge against move line.
00142         sint    sgnEdge0, sgnEdge1;
00143         sgnEdge0= fsgn(edgeD0);
00144         sgnEdge1= fsgn(edgeD1);
00145 
00146         // should not have this case, because tested before with (sgnMove==0 && sgnMove1==0).
00147         nlassert(sgnEdge0!=0 || sgnEdge1!=0);
00148 
00149 
00150         // if on same side of the line, no collision against this edge.
00151         if( sgnEdge0==sgnEdge1 )
00152                 return 1;
00153 
00154         // Here the edges intersect, but ensure that there is no limit problem.
00155         if(sgnEdge0==0 || sgnEdge1==0)
00156         {
00157                 moveBug= TraverseEndPoint;
00158                 return -1;
00159         }
00160         else if(sgnMove1==0)
00161         {
00162                 moveBug= StopOnEdge;
00163                 return -1;
00164         }
00165         else if(sgnMove0==0)
00166         {
00167                 // this should not arrive.
00168                 moveBug= StartOnEdge;
00169                 return -1;
00170         }
00171 
00172 
00173         // Here, there is a normal collision, just compute it.
00174         // Because of Division, there is a precision lost in double. So compute a CRational64.
00175         // First, compute numerator and denominator in the highest precision. this is 1024*1024 because of prec multiplication.
00176         double          numerator= (0-moveD0)*1024*1024;
00177         double          denominator= (moveD1-moveD0)*1024*1024;
00178         sint64          numeratorInt= (sint64)numerator;
00179         sint64          denominatorInt= (sint64)denominator;
00180 /*
00181         nlassert(numerator == numeratorInt);
00182         nlassert(denominator == denominatorInt);
00183 */
00184         if (numerator != numeratorInt)
00185                 nlwarning("numerator(%f) != numeratorInt(%"NL_I64"d)", numerator, numeratorInt);
00186         if (denominator != denominatorInt)
00187                 nlwarning("denominator(%f) != denominatorInt(%"NL_I64"d)", denominator, denominatorInt);
00188 
00189         return CRational64(numeratorInt, denominatorInt);
00190 }


Field Documentation

float NLPACS::CEdgeCollide::A0
 

Definition at line 190 of file edge_collide.h.

Referenced by make(), and testCircleMove().

float NLPACS::CEdgeCollide::A1
 

Definition at line 190 of file edge_collide.h.

Referenced by make(), and testCircleMove().

float NLPACS::CEdgeCollide::C
 

Definition at line 191 of file edge_collide.h.

Referenced by make(), testBBoxMove(), and testCircleMove().

CVector2f NLPACS::CEdgeCollide::Dir
 

Definition at line 189 of file edge_collide.h.

CVector2f NLPACS::CEdgeCollide::Norm
 

Definition at line 189 of file edge_collide.h.

Referenced by make(), testBBoxMove(), testCircleMove(), and NLPACS::CGlobalRetriever::testMovementWithCollisionChains().

CVector2f NLPACS::CEdgeCollide::P0
 

Definition at line 187 of file edge_collide.h.

CVector2f NLPACS::CEdgeCollide::P1
 

Definition at line 188 of file edge_collide.h.


The documentation for this class was generated from the following files:
Generated on Tue Mar 16 14:12:14 2004 for NeL by doxygen 1.3.6