CollisionDetectionNamespace::Collision_detector_Triangles_Distance Class Reference

Collision detector to test 2 Triangles with distance calculation. More...

#include <collision_detectors.h>

Inheritance diagram for CollisionDetectionNamespace::Collision_detector_Triangles_Distance:

CollisionDetectionNamespace::Collison_Detector_IFace

List of all members.

Public Member Functions

 Collision_detector_Triangles_Distance ()
 Class constructor.
CollisionReport FindCollision (void *pNode1, void *pNode2)

Private Member Functions

float closestPointsSegmentSegment (VECTOR3 p1, VECTOR3 q1, VECTOR3 p2, VECTOR3 q2, VECTOR3 &C1, VECTOR3 &C2)
float distanceSegmentSegment (VECTOR3 p1, VECTOR3 q1, VECTOR3 p2, VECTOR3 q2)
float distanceVertexTriangle (VECTOR3 P, Triangle triangle)
VECTOR3 closestPointVertexTriangle (VECTOR3 p, Triangle triangle)
float clamp (float n, float min, float max)


Detailed Description

Collision detector to test 2 Triangles with distance calculation.

Definition at line 101 of file collision_detectors.h.


Constructor & Destructor Documentation

CollisionDetectionNamespace::Collision_detector_Triangles_Distance::Collision_detector_Triangles_Distance (  )  [inline]

Class constructor.

Definition at line 105 of file collision_detectors.h.

00105 {;}


Member Function Documentation

CollisionReport Collision_detector_Triangles_Distance::FindCollision ( void *  pNode1,
void *  pNode2 
) [virtual]

Detect collision

Parameters:
[in] object 1
[in] object 2
Returns:
CollisionReport filled with collision detection results

Implements CollisionDetectionNamespace::Collison_Detector_IFace.

Definition at line 271 of file collision_detectors.cpp.

00272 {
00273        CollisionReport collisionReport;
00274 
00275        Triangle* a = (Triangle*) pNode1;
00276        Triangle* b = (Triangle*) pNode2;
00277 
00278        //float fDistance = 0;
00279        VECTOR3 C1, C2;
00280 
00281        VECTOR3 closestPt;
00282 
00283        // test all segments against both triangles
00284        
00285        collisionReport.fSqueredSeparationDistance = closestPointsSegmentSegment(a->v1,a->v2,b->v1,b->v2,C1,C2);
00286        closestPt = (C1 + (C2 - C1)/2);
00287        //fDistance = distanceSegmentSegment(a->v1,a->v2,b->v1,b->v2);
00288 
00289        float d = closestPointsSegmentSegment(a->v1,a->v2,b->v1,b->v3,C1,C2);
00290        if ( d < collisionReport.fSqueredSeparationDistance)
00291        {      
00292               collisionReport.fSqueredSeparationDistance = d;
00293               closestPt = (C1 + (C2 - C1)/2);
00294        }
00295        //float d = distanceSegmentSegment(a->v1,a->v2,b->v1,b->v3);
00296        //if (d < fDistance)
00297        //     fDistance = d;
00298 
00299        d = closestPointsSegmentSegment(a->v1,a->v2,b->v2,b->v3,C1,C2);
00300        if ( d < collisionReport.fSqueredSeparationDistance)
00301        {      
00302               collisionReport.fSqueredSeparationDistance = d;
00303               closestPt = (C1 + (C2 - C1)/2);
00304        }
00305 
00306        //d = distanceSegmentSegment(a->v1,a->v2,b->v2,b->v3);
00307        //if (d < fDistance)
00308        //     fDistance = d;
00309        
00310 
00311        d = closestPointsSegmentSegment(a->v1,a->v3,b->v1,b->v2,C1,C2);
00312        if ( d < collisionReport.fSqueredSeparationDistance)
00313        {      
00314               collisionReport.fSqueredSeparationDistance = d;
00315               closestPt = (C1 + (C2 - C1)/2);
00316        }
00317 
00318        //d = distanceSegmentSegment(a->v1,a->v3,b->v1,b->v2);
00319        //if (d < fDistance)
00320        //     fDistance = d;
00321 
00322 
00323        d = closestPointsSegmentSegment(a->v1,a->v3,b->v1,b->v3,C1,C2);
00324        if ( d < collisionReport.fSqueredSeparationDistance)
00325        {      
00326               collisionReport.fSqueredSeparationDistance = d;
00327               closestPt = (C1 + (C2 - C1)/2);
00328        }
00329 
00330        //d = distanceSegmentSegment(a->v1,a->v3,b->v1,b->v3);
00331        //if (d < fDistance)
00332        //     fDistance = d;
00333 
00334        d = closestPointsSegmentSegment(a->v1,a->v3,b->v2,b->v3,C1,C2);
00335        if ( d < collisionReport.fSqueredSeparationDistance)
00336        {      
00337               collisionReport.fSqueredSeparationDistance = d;
00338               closestPt = (C1 + (C2 - C1)/2);
00339        }
00340 
00341        //d = distanceSegmentSegment(a->v1,a->v3,b->v2,b->v3);
00342        //if (d < fDistance)
00343        //     fDistance = d;
00344 
00345 
00346        d = closestPointsSegmentSegment(a->v2,a->v3,b->v1,b->v2,C1,C2);
00347        if ( d < collisionReport.fSqueredSeparationDistance)
00348        {      
00349               collisionReport.fSqueredSeparationDistance = d;
00350               closestPt = (C1 + (C2 - C1)/2);
00351        }
00352 
00353        //d = distanceSegmentSegment(a->v2,a->v3,b->v1,b->v2);
00354        //if (d < fDistance)
00355        //     fDistance = d;
00356 
00357 
00358        d = closestPointsSegmentSegment(a->v2,a->v3,b->v1,b->v3,C1,C2);
00359        if ( d < collisionReport.fSqueredSeparationDistance)
00360        {      
00361               collisionReport.fSqueredSeparationDistance = d;
00362               closestPt = (C1 + (C2 - C1)/2);
00363        }
00364 
00365        //d = distanceSegmentSegment(a->v2,a->v3,b->v1,b->v3);
00366        //if (d < fDistance)
00367        //     fDistance = d;
00368 
00369 
00370        d = closestPointsSegmentSegment(a->v2,a->v3,b->v2,b->v3,C1,C2);
00371        if ( d < collisionReport.fSqueredSeparationDistance)
00372        {      
00373               collisionReport.fSqueredSeparationDistance = d;
00374               closestPt = (C1 + (C2 - C1)/2);
00375        }
00376 
00377        //d = distanceSegmentSegment(a->v2,a->v3,b->v2,b->v3);
00378        //if (d < fDistance)
00379        //     fDistance = d;
00380 
00381 
00382        // Test all points against both triangles
00383 
00384 
00385        VECTOR3 pt = closestPointVertexTriangle(a->v1,*b);
00386        VECTOR3 v = (a->v1 - pt);
00387        d =  v.Dot(v);
00388        if ( d < collisionReport.fSqueredSeparationDistance)
00389        {
00390               collisionReport.fSqueredSeparationDistance = d;
00391               closestPt = (pt + (v / 2));
00392        }
00393 
00394 
00395        //d = distanceVertexTriangle(a->v1,*b);
00396        //if (d < fDistance)
00397        //     fDistance = d;
00398 
00399 
00400        pt = closestPointVertexTriangle(a->v2,*b);
00401        v = (a->v2 - pt);
00402        d =  v.Dot(v);
00403        if ( d < collisionReport.fSqueredSeparationDistance)
00404        {
00405               collisionReport.fSqueredSeparationDistance = d;
00406               closestPt = (pt + (v / 2));
00407        }
00408 
00409 
00410        //d = distanceVertexTriangle(a->v2,*b);
00411        //if (d < fDistance)
00412        //     fDistance = d;
00413 
00414        pt = closestPointVertexTriangle(a->v3,*b);
00415        v = (a->v3 - pt);
00416        d =  v.Dot(v);
00417        if ( d < collisionReport.fSqueredSeparationDistance)
00418        {
00419               collisionReport.fSqueredSeparationDistance = d;
00420               closestPt = (pt + (v / 2));
00421        }
00422 
00423        //d = distanceVertexTriangle(a->v3,*b);
00424        //if (d < fDistance)
00425        //     fDistance = d;
00426 
00427 
00428        pt = closestPointVertexTriangle(b->v1,*a);
00429        v = (b->v1 - pt);
00430        d =  v.Dot(v);
00431        if ( d < collisionReport.fSqueredSeparationDistance)
00432        {
00433               collisionReport.fSqueredSeparationDistance = d;
00434               closestPt = (pt + (v / 2));
00435        }
00436 
00437 
00438        //d = distanceVertexTriangle(b->v1,*a);
00439        //if (d < fDistance)
00440        //     fDistance = d;
00441 
00442        pt = closestPointVertexTriangle(b->v2,*a);
00443        v = (b->v2 - pt);
00444        d =  v.Dot(v);
00445        if ( d < collisionReport.fSqueredSeparationDistance)
00446        {
00447               collisionReport.fSqueredSeparationDistance = d;
00448               closestPt = (pt + (v / 2));
00449        }
00450 
00451        //d = distanceVertexTriangle(b->v2,*a);
00452        //if (d < fDistance)
00453        //     fDistance = d;
00454 
00455        pt = closestPointVertexTriangle(b->v3,*a);
00456        v = (b->v3 - pt);
00457        d =  v.Dot(v);
00458        if ( d < collisionReport.fSqueredSeparationDistance)
00459        {
00460               collisionReport.fSqueredSeparationDistance = d;
00461               closestPt = (pt + (v / 2));
00462        }
00463 
00464        collisionReport.collisionPoints.push_back(closestPt);
00465        //d = distanceVertexTriangle(b->v3,*a);
00466        //if (d < fDistance)
00467        //     fDistance = d;
00468 
00469 
00470        return collisionReport;
00471 }

float Collision_detector_Triangles_Distance::closestPointsSegmentSegment ( VECTOR3  p1,
VECTOR3  q1,
VECTOR3  p2,
VECTOR3  q2,
VECTOR3 C1,
VECTOR3 C2 
) [private]

Closest points test for 2 segments

Parameters:
[in] start point of segment 1
[in] end point of segment 1
[in] start point of segment 2
[in] end point of segment 2
[out] closest point on segment 1
[out] closest point on segment 2
Returns:
minimal distance between segments

Definition at line 474 of file collision_detectors.cpp.

00475 {
00476        float fDistance = 0;
00477        float s,t;    // parameters of closest points
00478 
00479        VECTOR3 d1 = q1 - p1; // Direction vector of S1
00480        VECTOR3 d2 = q2 - p2; // Direction vector of S2
00481 
00482        VECTOR3 r = p1 - p2;
00483 
00484        float a = d1.Dot(d1); // Squered lenght of S1
00485        float e = d2.Dot(d2); // Squered lenght of S2
00486 
00487        float f = d2.Dot(r);
00488        
00489        if (a <= EPSILON && e <= EPSILON)
00490        {
00491               // Both segments degenerate into points
00492               s = t = 0.0f;
00493        }
00494        else if (a <= EPSILON)
00495        {
00496               // first segment degenerates into point
00497               s = 0.0f;
00498               t = clamp(f/e,0.0f,1.0f);
00499        }
00500        else
00501        {
00502               float c = d1.Dot(r);
00503               if ( e <= EPSILON)
00504               {
00505                      // second segment degenerates into point
00506                      t = 0.0f;
00507                      s = clamp(-c/a,0.0f,1.0f);
00508               }
00509               else
00510               {
00511                      float b = d1.Dot(d2);
00512                      float denom = a*e - b*b;
00513 
00514                      // if segments not parallel compute closest point on L1 to L2
00515                      //     and clamp it to segment S1, else pick s
00516                      if (denom != 0.0f)
00517                             s = clamp((b*f-c*e)/denom,0.0f,1.0f);
00518                      else
00519                             s = 0.0f;
00520 
00521                      // Compute closest point on L2 closest to S1(s)
00522                      t = (b*s + f) / e;
00523 
00524                      // if t in [0,1] done. Else clamp t, recompute s for the new value t
00525                      if ( t < 0.0f)
00526                      {
00527                             t = 0.0f;
00528                             s = clamp(-c/a,0.0f, 1.0f);
00529                      }
00530                      else if (t > 1.0f)
00531                      {
00532                             t = 1.0f;
00533                             s = clamp((b-c)/a,0.0f, 1.0f);
00534                      }
00535               }
00536        }
00537 
00538        C1 = p1 + d1*s;
00539        C2 = p2 + d2*t;
00540 
00541        VECTOR3 x = C2-C1;
00542 
00543        fDistance = x.Dot(x);
00544 
00545        return fDistance;
00546 }

float Collision_detector_Triangles_Distance::distanceSegmentSegment ( VECTOR3  p1,
VECTOR3  q1,
VECTOR3  p2,
VECTOR3  q2 
) [private]

Distance test for 2 segments

Parameters:
[in] start point of segment 1
[in] end point of segment 1
[in] start point of segment 2
[in] end point of segment 2
Returns:
minimal distance between segments

Definition at line 549 of file collision_detectors.cpp.

00550 {
00551        float fDistance = 0;
00552        float s,t;    // parameters of closest points
00553 
00554        VECTOR3 d1 = q1 - p1; // Direction vector of S1
00555        VECTOR3 d2 = q2 - p2; // Direction vector of S2
00556 
00557        VECTOR3 r = p1 - p2;
00558 
00559        float a = d1.Dot(d1); // Squered lenght of S1
00560        float e = d2.Dot(d2); // Squered lenght of S2
00561 
00562        float f = d2.Dot(r);
00563        
00564        if (a <= EPSILON && e <= EPSILON)
00565        {
00566               // Both segments degenerate into points
00567               s = t = 0.0f;
00568        }
00569        else if (a <= EPSILON)
00570        {
00571               // first segment degenerates into point
00572               s = 0.0f;
00573               t = clamp(f/e,0.0f,1.0f);
00574        }
00575        else
00576        {
00577               float c = d1.Dot(r);
00578               if ( e <= EPSILON)
00579               {
00580                      // second segment degenerates into point
00581                      t = 0.0f;
00582                      s = clamp(-c/a,0.0f,1.0f);
00583               }
00584               else
00585               {
00586                      float b = d1.Dot(d2);
00587                      float denom = a*e - b*b;
00588 
00589                      // if segments not parallel compute closest point on L1 to L2
00590                      //     and clamp it to segment S1, else pick s
00591                      if (denom != 0.0f)
00592                             s = clamp((b*f-c*e)/denom,0.0f,1.0f);
00593                      else
00594                             s = 0.0f;
00595 
00596                      // Compute closest point on L2 closest to S1(s)
00597                      t = (b*s + f) / e;
00598 
00599                      // if t in [0,1] done. Else clamp t, recompute s for the new value t
00600                      if ( t < 0.0f)
00601                      {
00602                             t = 0.0f;
00603                             s = clamp(-c/a,0.0f, 1.0f);
00604                      }
00605                      else if (t > 1.0f)
00606                      {
00607                             t = 1.0f;
00608                             s = clamp((b-c)/a,0.0f, 1.0f);
00609                      }
00610               }
00611        }
00612 
00613        VECTOR3 c1 = p1 + d1*s;
00614        VECTOR3 c2 = p2 + d2*t;
00615 
00616        VECTOR3 x = c2-c1;
00617 
00618        fDistance = x.Dot(x);
00619 
00620        return fDistance;
00621 }

float Collision_detector_Triangles_Distance::distanceVertexTriangle ( VECTOR3  P,
Triangle  triangle 
) [private]

Distance test for vertex and triangle

Parameters:
[in] vertex 
[in] triangle 
Returns:
minimal distance between vertex and triangle

Definition at line 630 of file collision_detectors.cpp.

00631 {
00632        float fDistance = 0;
00633        VECTOR3 closestPoint = closestPointVertexTriangle(p,triangle);
00634 
00635        
00636        VECTOR3 d = p - closestPoint;
00637 
00638 
00639        fDistance = d.Dot(d);
00640 
00641        return fDistance;
00642 }

VECTOR3 Collision_detector_Triangles_Distance::closestPointVertexTriangle ( VECTOR3  p,
Triangle  triangle 
) [private]

Closest point test for vertex and triangle

Parameters:
[in] vertex 
[in] triangle 
Returns:
closest point between vertex and triangle on triangle

Definition at line 644 of file collision_detectors.cpp.

00645 {
00646        VECTOR3 ab = triangle.v2 - triangle.v1;
00647        VECTOR3 ac = triangle.v3 - triangle.v1;
00648        VECTOR3 ap = p - triangle.v1;
00649 
00650        float d1 = ab.Dot(ap);
00651        float d2 = ac.Dot(ap);
00652 
00653        // check if p in vertex region outside A
00654        if ( d1 <= 0.0f && d2 <= 0.0f) // Barycentric coordinates (1,0,0)
00655        {
00656               return triangle.v1;
00657        }
00658        
00659        // check if p in vertex region outside B
00660        VECTOR3 bp = p - triangle.v2;
00661        float d3 = ab.Dot(bp);
00662        float d4 = ac.Dot(bp);
00663 
00664        if (d3 >= 0.0f && d4 <= d3) // Barycentric coordinates (0,1,0)
00665               return triangle.v2;
00666               
00667        // check if p in edge projection of AB
00668        float vc = d1*d4 - d3*d2;
00669        if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f)
00670        {
00671               float v = d1 / (d1-d3);
00672               return triangle.v1+v*ab;
00673        }
00674 
00675        // check if p in vertex region outside A
00676        VECTOR3 cp = p - triangle.v3;
00677        float d5 = ab.Dot(cp);
00678        float d6 = ac.Dot(cp);
00679        if (d6 >= 0.0f && d5 <= d6) // Barycentric coordinates (0,0,1)
00680               return triangle.v3;
00681 
00682        // check if p in edge projection of AC
00683        float vb = d5*d2 - d1*d6;
00684        if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f)
00685        {
00686               float w = d2 / (d2-d6);
00687               return triangle.v1+w*ac;
00688        }
00689 
00690        // check if p in edge projection of BC
00691        float va = d3*d6 - d5*d4;
00692        if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f)
00693        {
00694               float w = (d4 - d3) / ((d4-d3)+(d5-d6));
00695               return triangle.v2 + w * (triangle.v3-triangle.v2);
00696        }
00697 
00698        // p is inside face region
00699        float denom = 1.0f / (va +vb +vc);
00700        float v = vb * denom;
00701        float w = vc * denom;
00702 
00703        return triangle.v1 + ab*v + ac*w;
00704 }

float Collision_detector_Triangles_Distance::clamp ( float  n,
float  min,
float  max 
) [private]

clamp number into an interval

Parameters:
[in] number to clamp
[in] interval min
[in] interval max
Returns:
clamped number

Definition at line 623 of file collision_detectors.cpp.

00624 {
00625        if (n < min) return min;
00626        if (n > max) return max;
00627        return n;
00628 }


The documentation for this class was generated from the following files:

Generated on Tue Mar 10 14:41:39 2009 for VRUT by  doxygen 1.5.5