00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <assert.h>
00016 #include <math.h>
00017 #pragma warning( disable : 4786 )
00018
00019
00020
00021 #include "synchronization/semaphore.h"
00022 #include "PL_SimplexSubdivision.h"
00023 #include "opengl/glos.h"
00024 #include <gl/gl.h>
00025
00026
00027
00028
00029
00030
00031 PL_SimplexSubdivision::PL_SimplexSubdivision()
00032 :
00033 m_NodeStart( 0 ),
00034 m_NodeGoal( 0 ),
00035 m_Compare( this ),
00036 m_SuspiciousNodesAndVolumes( m_Compare )
00037 {
00038 }
00039
00040
00041
00042
00043
00044
00045
00046 PL_SimplexSubdivision::~PL_SimplexSubdivision()
00047 {
00048
00049 }
00050
00051
00052
00053
00054
00055
00056 void PL_SimplexSubdivision::AddEdge( const int node0, const int node1 )
00057 {
00058 if( !IsAdjacent( node0, node1 ) )
00059 {
00060 return;
00061 }
00062
00063 Node& n0 = m_Nodes[ node0 ];
00064 Node& n1 = m_Nodes[ node1 ];
00065 n0.AddNeighbor( node1 );
00066 n1.AddNeighbor( node0 );
00067 }
00068
00069
00070
00071
00072
00073
00074 int PL_SimplexSubdivision::AddNode
00075 (
00076 const Configuration& min,
00077 const Configuration& max
00078 )
00079 {
00080 Node addme;
00081 #pragma message( "##### Magic numbers are bad" )
00082 addme.m_DistanceFromStart = 99999999;
00083 addme.m_Min = min;
00084 addme.m_Max = max;
00085 addme.m_Alive = true;
00086 addme.m_NodesAdjacent.clear();
00087 addme.m_LocationOfCollision = ( min + max ) / 2;
00088 this->m_Nodes.push_back( addme );
00089 int returnMe = m_Nodes.size() - 1;
00090 this->m_OpenList.insert( returnMe );
00091 return returnMe;
00092 }
00093
00094
00095
00096
00097
00098
00099 void PL_SimplexSubdivision::AddSuspiciousNode( const int nodeNum )
00100 {
00101 m_SuspiciousNodesAndVolumes.insert( nodeNum );
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111 void PL_SimplexSubdivision::AddToOpenList( const int nodeNum )
00112 {
00113
00114
00115
00116
00117
00118
00119
00120
00121 {
00122 m_OpenList.insert( nodeNum );
00123 }
00124 }
00125
00126
00127
00128
00129
00130
00131
00132 PL_SimplexSubdivision::CollisionType PL_SimplexSubdivision::CollisionCheck( const int n0, const int n1 )
00133 {
00134 Node& node0 = m_Nodes[ n0 ];
00135 Node& node1 = m_Nodes[ n1 ];
00136
00137
00138
00139
00140
00141 int n0Neighbor = -1;
00142 int n1Neighbor = -1;
00143
00144 int i;
00145 int size = node0.m_NodesAdjacent.size();
00146 for( i = 0; i < size; i++ )
00147 {
00148 if( node0.m_NodesAdjacent[ i ] == n1 )
00149 {
00150 n0Neighbor = i;
00151 break;
00152 }
00153 }
00154 assert( n0Neighbor != -1 );
00155
00156 size = node1.m_NodesAdjacent.size();
00157 for( i = 0; i < size; i++ )
00158 {
00159 if( node1.m_NodesAdjacent[ i ] == n0 )
00160 {
00161 n1Neighbor = i;
00162 break;
00163 }
00164 }
00165 assert( n1Neighbor != -1 );
00166
00167
00168
00169
00170 if( node0.m_LinkType[ n0Neighbor ] != CT_UNKNOWN )
00171 {
00172 return node0.m_LinkType[ n0Neighbor ];
00173 }
00174
00175
00176
00177
00178
00179 Configuration c0 = node0.Center();
00180 Configuration c1 = node1.Center();
00181 bool collision = collisionDetector->IsInterfering( c0 );
00182 collision = ( collision || collisionDetector->IsInterfering( c1 ) );
00183 collision = ( collision || collisionDetector->IsInterferingLinear( c0, c1 ) );
00184 CollisionType ct;
00185 if( collision )
00186 {
00187 ct = CT_COLLISION;
00188
00189
00190 Configuration c = collisionDetector->GetLastValid();
00191 bool n0contains = node0.ContainsCompletely( c );
00192 bool n1contains = node1.ContainsCompletely( c );
00193
00194 if( n0contains && !n1contains )
00195 {
00196 double minx = node0.m_Min[ 0 ];
00197 double miny = node0.m_Min[ 1 ];
00198 double maxx = node0.m_Max[ 0 ];
00199 double maxy = node0.m_Max[ 1 ];
00200 double cx = c[ 0 ];
00201 double cy = c[ 1 ];
00202 node0.m_LocationOfCollision = c;
00203 }
00204 else if( n1contains && !n0contains )
00205 {
00206 node1.m_LocationOfCollision = c;
00207 }
00208 else
00209 {
00210
00211 }
00212 }
00213 else
00214 {
00215 ct = CT_FREE;
00216 }
00217 node0.m_LinkType[ n0Neighbor ] = ct;
00218 node1.m_LinkType[ n1Neighbor ] = ct;
00219 return ct;
00220 }
00221
00222
00223
00224
00225
00226
00227 void PL_SimplexSubdivision::ConnectStartAndGoal()
00228 {
00229
00230
00231
00232 bool collision = true;
00233 if( collision )
00234 {
00235 Configuration startNode = m_Nodes[ m_NodeStart ].Center();
00236 collision = collisionDetector->IsInterferingLinear( GetStartConfig(), startNode );
00237 if( collision )
00238 {
00239 SubdivideNode( m_NodeStart );
00240 }
00241 else
00242 {
00243 m_Nodes[ m_NodeStart ].m_DistanceFromStart = 0;
00244 }
00245 }
00246
00247
00248
00249
00250 collision = true;
00251 if( collision )
00252 {
00253 Configuration goalNode = m_Nodes[ m_NodeGoal ].Center();
00254 collision = collisionDetector->IsInterferingLinear( GetGoalConfig(), goalNode );
00255 if( collision )
00256 {
00257 SubdivideNode( m_NodeGoal );
00258 }
00259 }
00260 }
00261
00262
00263
00264
00265
00266
00267
00268 void PL_SimplexSubdivision::DeleteEdge( const int node0, const int node1 )
00269 {
00270 Node& n0 = m_Nodes[ node0 ];
00271 Node& n1 = m_Nodes[ node1 ];
00272 n0.RemoveNeighbor( node1 );
00273 n1.RemoveNeighbor( node0 );
00274 }
00275
00276
00277
00278
00279
00280
00281 void PL_SimplexSubdivision::DeleteNode( const int nodeNum )
00282 {
00283 Node& node = m_Nodes[ nodeNum ];
00284 node.m_Alive = false;
00285
00286
00287 int i;
00288 int size = node.m_NodesAdjacent.size();
00289 for( i = size - 1; i >= 0; i-- )
00290 {
00291 int neighbor = node.m_NodesAdjacent[ i ];
00292 DeleteEdge( nodeNum, neighbor );
00293 }
00294
00295 m_OpenList.erase( nodeNum );
00296 m_ClosedList.erase( nodeNum );
00297 }
00298
00299
00300
00301
00302
00303
00304 bool PL_SimplexSubdivision::DrawExplicit () const
00305 {
00306 Semaphore semaphore( this->guid );
00307 semaphore.Lock();
00308
00309 glClearColor( 0.0f, 0.0f, 0.2f, 1.0f );
00310 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00311
00312
00313
00314
00315 glDisable( GL_LIGHTING );
00316 glDisable( GL_DEPTH_TEST );
00317
00318 int i = 0;
00319 glColor4d( 1.0, 1.0, 1.0, 1.0 );
00320 glPointSize( 3.0 );
00321
00322 int dof = GetGoalConfig().DOF();
00323
00324
00325 int size = m_Nodes.size();
00326 for( i = 0; i < size; i++ )
00327 {
00328
00329
00330
00331 const Node& node = m_Nodes[ i ];
00332 node.DrawExplicit();
00333 }
00334
00335
00336
00337
00338
00339
00340
00341
00342 glBegin( GL_LINES );
00343 glLineWidth( 2.0 );
00344
00345 int n;
00346 int nSize = m_Nodes.size();
00347 for( n = 0; n < nSize; n++ )
00348 {
00349 const Node& me = m_Nodes[ n ];
00350 if( !me.m_Alive )
00351 {
00352 continue;
00353 }
00354 int size = me.m_NodesAdjacent.size();
00355 for( i = 0; i < size; i++ )
00356 {
00357 int neighborInt = me.m_NodesAdjacent[ i ];
00358 assert( neighborInt >= 0 );
00359 CollisionType ct = me.m_LinkType[ i ];
00360 switch( ct )
00361 {
00362 case CT_FREE:
00363 {
00364 glColor4f( 0.0f, 1.0f, 0.0f, 1.0f );
00365 break;
00366 }
00367 case CT_COLLISION:
00368 {
00369 glColor4f( 1.0f, 0.0f, 0.0f, 1.0f );
00370 break;
00371 }
00372 default:
00373 {
00374 glColor4f( 0.5f, 0.5f, 0.5f, 0.3f );
00375 break;
00376 }
00377 }
00378 const Node& neighborNode = m_Nodes[ neighborInt ];
00379 Configuration neighbor = neighborNode.Center();
00380 Configuration myC = me.Center();
00381 double mX = myC[ 0 ];
00382 double mY = myC[ 1 ];
00383 double nX = neighbor[ 0 ];
00384 double nY = neighbor[ 1 ];
00385 glVertex3d( mX, mY, 0 );
00386 glVertex3d( nX, nY, 0 );
00387 }
00388 }
00389 glEnd();
00390
00391
00392
00393
00394 glColor3f( 1.0f, 1.0f, 1.0f );
00395 glBegin( GL_POINTS );
00396 double n0 = 0;
00397 double n1 = 0;
00398 double n2 = 0;
00399 if( dof > 0 )
00400 {
00401 n0 = GetGoalConfig()[ 0 ];
00402 }
00403 if( dof > 1 )
00404 {
00405 n1 = GetGoalConfig()[ 1 ];
00406 }
00407 if( dof > 2 )
00408 {
00409 n2 = GetGoalConfig()[ 2 ];
00410 }
00411 glVertex3f( n0, n1, n2 );
00412 if( dof > 0 )
00413 {
00414 n0 = GetStartConfig()[ 0 ];
00415 }
00416 if( dof > 1 )
00417 {
00418 n1 = GetStartConfig()[ 1 ];
00419 }
00420 if( dof > 2 )
00421 {
00422 n2 = GetStartConfig()[ 2 ];
00423 }
00424 glVertex3f( n0, n1, n2 );
00425 glEnd();
00426
00427 semaphore.Unlock();
00428 return true;
00429 }
00430
00431
00432
00433
00434
00435
00436 bool PL_SimplexSubdivision::IsAdjacent( int node0, int node1 )
00437 {
00438 int overlapping = 0;
00439 int adjacent = 0;
00440
00441 Node& n0 = m_Nodes[ node0 ];
00442 Node& n1 = m_Nodes[ node1 ];
00443 int i;
00444 int size = n0.m_Max.DOF();
00445 for( i = 0; i < size; i++ )
00446 {
00447 double aMin = n0.m_Min[ i ];
00448 double aMax = n0.m_Max[ i ];
00449 double bMin = n1.m_Min[ i ];
00450 double bMax = n1.m_Max[ i ];
00451
00452 if( ( aMin <= bMin ) && ( aMax > bMin ) )
00453 {
00454 overlapping++;
00455 continue;
00456 }
00457 if( ( bMin <= aMin ) && ( bMax > aMin ) )
00458 {
00459 overlapping++;
00460 continue;
00461 }
00462 if( ( aMax == bMin ) || ( bMax == aMin ) )
00463 {
00464 adjacent++;
00465 continue;
00466 }
00467 }
00468 if( ( adjacent == 1 ) && ( overlapping + adjacent == size ) )
00469 {
00470 return true;
00471 }
00472 return false;
00473 }
00474
00475
00476
00477
00478
00479
00480 bool PL_SimplexSubdivision::Plan ()
00481 {
00482
00483 StartTimer();
00484
00485 m_Nodes.clear();
00486
00487
00488
00489
00490 Configuration min;
00491 Configuration max;
00492 min = GetStartConfig();
00493 max = GetStartConfig();
00494 int i;
00495 int size = min.DOF();
00496 for( i = 0; i < size; i++ )
00497 {
00498 min[ i ] = collisionDetector->JointMin( i );
00499 max[ i ] = collisionDetector->JointMax( i );
00500 }
00501
00502
00503
00504
00505 int firstNode = AddNode( min, max );
00506 m_NodeStart = firstNode;
00507 m_NodeGoal = firstNode;
00508
00509
00510
00511
00512 ConnectStartAndGoal();
00513
00514
00515 AddToOpenList( m_NodeStart );
00516
00517 bool foundGoal = SearchForGoal();
00518 Semaphore semaphore( this->guid );
00519
00520 while( !foundGoal )
00521 {
00522 if( HasTimeLimitExpired() )
00523 {
00524 return false;
00525 }
00526 if( this->m_UseSemaphores )
00527 {
00528 semaphore.Lock();
00529 }
00530 SubdivideLargestNode();
00531 foundGoal = SearchForGoal();
00532
00533 if( this->m_UseSemaphores )
00534 {
00535 semaphore.Unlock();
00536 }
00537 }
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585 return true;
00586 }
00587
00588
00589
00590
00591
00592
00593 bool PL_SimplexSubdivision::SearchForGoal()
00594 {
00595
00596
00597
00598 while( m_OpenList.size() != 0 )
00599 {
00600 int nodesRemainingInOpenList = m_OpenList.size();
00601 int nodeToExpand = *( m_OpenList.begin() );
00602 m_OpenList.erase( m_OpenList.begin() );
00603 Node& n = m_Nodes[ nodeToExpand ];
00604
00605
00606 int i;
00607 int size = n.m_NodesAdjacent.size();
00608 for( i = 0; i < size; i++ )
00609 {
00610 int neighbor = n.m_NodesAdjacent[ i ];
00611 Node& neighborNode = m_Nodes[ neighbor ];
00612 if( neighborNode.m_DistanceFromStart >= n.m_DistanceFromStart )
00613 {
00614 continue;
00615 }
00616 m_ClosedList.insert( nodeToExpand );
00617
00618
00619 PL_SimplexSubdivision::CollisionType ct = CollisionCheck( nodeToExpand, neighbor );
00620 if( ct == CT_FREE )
00621 {
00622
00623
00624
00625 double distance = ( n.Center() - neighborNode.Center() ).Magnitude();
00626 double newDistance = neighborNode.m_DistanceFromStart + distance;
00627 if( newDistance >= n.m_DistanceFromStart )
00628 {
00629 continue;
00630 }
00631 n.m_DistanceFromStart = newDistance;
00632
00633 if( nodeToExpand == m_NodeGoal )
00634 {
00635 return true;
00636 }
00637
00638
00639
00640
00641 int j;
00642 int size = n.m_NodesAdjacent.size();
00643 for( j = 0; j < size; j++ )
00644 {
00645 int neighbor = n.m_NodesAdjacent[ j ];
00646 AddToOpenList( neighbor );
00647 }
00648 }
00649 else
00650 {
00651 Configuration collision = collisionDetector->GetLastIntersection();
00652 Node& n0 = m_Nodes[ neighbor ];
00653 Node& n1 = m_Nodes[ nodeToExpand ];
00654 bool n0contains = n0.Contains( collision );
00655 bool n1contains = n0.Contains( collision );
00656 if( n0contains )
00657 {
00658 AddSuspiciousNode( neighbor );
00659 }
00660 if( n1contains )
00661 {
00662 AddSuspiciousNode( nodeToExpand );
00663 }
00664 if( !n0contains && !n1contains )
00665 {
00666 AddSuspiciousNode( neighbor );
00667 AddSuspiciousNode( nodeToExpand );
00668 }
00669 }
00670 }
00671 }
00672 return false;
00673 }
00674
00675
00676
00677
00678
00679
00680 void PL_SimplexSubdivision::SubdivideLargestNode()
00681 {
00682
00683
00684
00685 int size = m_SuspiciousNodesAndVolumes.size();
00686 assert( size != 0 );
00687
00688 INTSET::value_type value = *( m_SuspiciousNodesAndVolumes.begin() );
00689 m_SuspiciousNodesAndVolumes.erase( m_SuspiciousNodesAndVolumes.begin() );
00690 int mostSuspiciousNode = value;
00691 double howBigWasIt = Volume( mostSuspiciousNode );
00692 SubdivideNode( mostSuspiciousNode );
00693 }
00694
00695
00696
00697
00698
00699
00700 void PL_SimplexSubdivision::SubdivideNode( int nodeNum )
00701 {
00702 Node subdivideMe = m_Nodes[ nodeNum ];
00703 Configuration min = subdivideMe.m_Min;
00704 Configuration max = subdivideMe.m_Max;
00705
00706
00707
00708
00709 int longestDimension = 0;
00710 double longestSize = 0;
00711 int i;
00712 int size = subdivideMe.m_Min.Length();
00713 for( i = 0; i < size; i++ )
00714 {
00715 double size = max[ i ] - min[ i ];
00716 if( size > longestSize )
00717 {
00718 longestSize = size;
00719 longestDimension = i;
00720 }
00721 }
00722
00723 double maxDim = max[ longestDimension ];
00724 double minDim = min[ longestDimension ];
00725 double halfWayPoint = subdivideMe.m_LocationOfCollision[ longestDimension ];
00726 Configuration minHi = max;
00727 minHi[ longestDimension ] = halfWayPoint;
00728 Configuration maxLo = min;
00729 maxLo[ longestDimension ] = halfWayPoint;
00730
00731 int loNumber = AddNode( min, minHi );
00732 int hiNumber = AddNode( maxLo, max );
00733 AddEdge( loNumber, hiNumber );
00734
00735 size = subdivideMe.m_NodesAdjacent.size();
00736 assert( size >= 0 );
00737 for( i = 0; i < size; i++ )
00738 {
00739 int originalNeighbor = subdivideMe.m_NodesAdjacent[ i ];
00740 AddEdge( loNumber, originalNeighbor );
00741 AddEdge( hiNumber, originalNeighbor );
00742 }
00743
00744
00745
00746
00747 bool needReconnect = false;
00748 if( nodeNum == m_NodeStart )
00749 {
00750 Node& a = m_Nodes[ loNumber ];
00751 Node& b = m_Nodes[ hiNumber ];
00752 if( a.Contains( GetStartConfig() ) )
00753 {
00754 m_NodeStart = loNumber;
00755 }
00756 else
00757 {
00758 m_NodeStart = hiNumber;
00759 assert( b.Contains( GetStartConfig() ) );
00760 }
00761 needReconnect = true;
00762 }
00763
00764 if( nodeNum == m_NodeGoal )
00765 {
00766 Node& a = m_Nodes[ loNumber ];
00767 Node& b = m_Nodes[ hiNumber ];
00768 if( a.Contains( GetGoalConfig()) )
00769 {
00770 m_NodeGoal = loNumber;
00771 }
00772 else
00773 {
00774 m_NodeGoal = hiNumber;
00775 assert( b.Contains( GetGoalConfig() ) );
00776 }
00777 needReconnect = true;
00778 }
00779 DeleteNode( nodeNum );
00780 if( needReconnect )
00781 {
00782 ConnectStartAndGoal();
00783 }
00784 }
00785
00786
00787
00788
00789
00790
00791 double PL_SimplexSubdivision::Volume( const int i ) const
00792 {
00793 return m_Nodes[ i ].Volume();
00794 }
00795
00796
00797
00798
00799
00800
00801
00802 void PL_SimplexSubdivision::Node::AddNeighbor( const int node )
00803 {
00804
00805
00806
00807
00808
00809
00810 std::vector< int >::iterator it;
00811 for( it = m_NodesAdjacent.begin(); it != m_NodesAdjacent.end(); it++ )
00812 {
00813 if( *it == node )
00814 {
00815 return;
00816 }
00817 }
00818
00819
00820 m_NodesAdjacent.push_back( node );
00821 m_LinkType.push_back( CT_UNKNOWN );
00822 }
00823
00824
00825
00826
00827
00828
00829 Configuration PL_SimplexSubdivision::Node::Center() const
00830 {
00831 assert( m_Alive );
00832 return ( m_Max + m_Min ) / 2;
00833 }
00834
00835
00836
00837
00838
00839
00840 bool PL_SimplexSubdivision::Node::Contains( const Configuration& c ) const
00841 {
00842 bool returnMe = true;
00843 int i;
00844 int size = m_Min.Length();
00845 for( i = 0; i < size; i++ )
00846 {
00847 if( m_Min[ i ] > c[ i ] )
00848 {
00849 return false;
00850 }
00851
00852 if( m_Max[ i ] < c[ i ] )
00853 {
00854 return false;
00855 }
00856 }
00857 return true;
00858 }
00859
00860
00861
00862
00863
00864
00865 bool PL_SimplexSubdivision::Node::ContainsCompletely( const Configuration& c ) const
00866 {
00867 bool returnMe = true;
00868 int i;
00869 int size = m_Min.Length();
00870 for( i = 0; i < size; i++ )
00871 {
00872 if( m_Min[ i ] >= c[ i ] )
00873 {
00874 return false;
00875 }
00876
00877 if( m_Max[ i ] <= c[ i ] )
00878 {
00879 return false;
00880 }
00881 }
00882 return true;
00883 }
00884
00885
00886
00887
00888
00889
00890 void PL_SimplexSubdivision::Node::DrawExplicit() const
00891 {
00892 if( !m_Alive )
00893 {
00894 return;
00895 }
00896
00897 ::glLineWidth( 1.0 );
00898
00899 double xMin = m_Min[ 0 ];
00900 double yMin = m_Min[ 1 ];
00901 double xMax = m_Max[ 0 ];
00902 double yMax = m_Max[ 1 ];
00903
00904 GlColor();
00905
00906 glBegin( GL_QUADS );
00907 glVertex3d( xMin, yMin, 0 );
00908 glVertex3d( xMax, yMin, 0 );
00909 glVertex3d( xMax, yMax, 0 );
00910 glVertex3d( xMin, yMax, 0 );
00911 glEnd();
00912
00913 glBegin( GL_LINE_LOOP );
00914 glVertex3d( xMin, yMin, 0 );
00915 glVertex3d( xMax, yMin, 0 );
00916 glVertex3d( xMax, yMax, 0 );
00917 glVertex3d( xMin, yMax, 0 );
00918 glEnd();
00919
00920 glBegin( GL_POINTS );
00921 glVertex3d( xMin, yMin, 0 );
00922 glVertex3d( xMax, yMin, 0 );
00923 glVertex3d( xMax, yMax, 0 );
00924 glVertex3d( xMin, yMax, 0 );
00925 glEnd();
00926 }
00927
00928
00929
00930
00931
00932
00933 void PL_SimplexSubdivision::Node::GlColor() const
00934 {
00935 bool isUnknown = true;
00936 bool isFree = true;
00937 bool isColliding = true;
00938 int i;
00939 int size = m_LinkType.size();
00940 for( i = 0; i < size; i++ )
00941 {
00942 if( m_LinkType[ i ] == CT_COLLISION )
00943 {
00944 isFree = false;
00945 }
00946
00947 if( m_LinkType[ i ] != CT_UNKNOWN )
00948 {
00949 isUnknown = false;
00950 }
00951
00952 if( m_LinkType[ i ] == CT_FREE )
00953 {
00954 isColliding = false;
00955 }
00956 }
00957
00958 if( isUnknown )
00959 {
00960 ::glColor4d( 1.0, 1.0, 1.0, 0.3 );
00961 }
00962 else if( isFree )
00963 {
00964 ::glColor4d( 0.0, 1.0, 0.0, 0.3 );
00965 }
00966 else if( isColliding )
00967 {
00968 ::glColor4d( 1.0, 0.0, 0.0, 0.3 );
00969 }
00970 else
00971 {
00972 ::glColor4d( 1.0, 1.0, 0.0, 0.3 );
00973 }
00974 }
00975
00976
00977
00978
00979
00980
00981
00982 bool PL_SimplexSubdivision::Node::IsClean() const
00983 {
00984 int i;
00985 int size = m_LinkType.size();
00986 for( i = 0; i < size; i++ )
00987 {
00988 if( m_LinkType[ i ] != CT_FREE )
00989 {
00990 return false;
00991 }
00992 }
00993 return true;
00994 }
00995
00996
00997
00998
00999
01000
01001
01002 void PL_SimplexSubdivision::Node::RemoveNeighbor( const int node )
01003 {
01004
01005
01006
01007 std::vector< int >::iterator it;
01008 std::vector< CollisionType >::iterator ctIt = m_LinkType.begin();
01009 for( it = m_NodesAdjacent.begin(); it != m_NodesAdjacent.end(); it++, ctIt++ )
01010 {
01011 if( *it == node )
01012 {
01013 m_NodesAdjacent.erase( it );
01014 m_LinkType.erase( ctIt );
01015 return;
01016 }
01017 }
01018
01019
01020
01021
01022
01023 }
01024
01025
01026
01027
01028
01029
01030 double PL_SimplexSubdivision::Node::Volume() const
01031 {
01032 double runningTotal = 1.0;
01033 int i;
01034 int size = m_Max.Length();
01035 for( i = 0; i < size; i++ )
01036 {
01037 double length = m_Max[ i ] - m_Min[ i ];
01038 runningTotal *= length;
01039 }
01040 return runningTotal;
01041 }
01042
01043
01044
01045
01046
01047
01048 PL_SimplexSubdivision::ComparisonFunction::ComparisonFunction( const PL_SimplexSubdivision* planner )
01049 :
01050 m_Planner( planner )
01051 {
01052 }
01053
01054
01055
01056
01057
01058
01059 PL_SimplexSubdivision::ComparisonFunction::ComparisonFunction( const ComparisonFunction& right )
01060 {
01061 m_Planner = right.m_Planner;
01062 }
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072 bool PL_SimplexSubdivision::ComparisonFunction::operator()
01073 (
01074 const int a,
01075 const int b
01076 )
01077
01078 {
01079 assert( m_Planner != NULL );
01080 double volA = m_Planner->Volume( a );
01081 double volB = m_Planner->Volume( b );
01082
01083
01084 if( volA > volB ) return true;
01085 if( volB > volA ) return false;
01086 if( a > b ) return true;
01087 return false;
01088 }