00001 #pragma warning( disable : 4786 )
00002 #include "synchronization\semaphore.h"
00003 #include "robots\r_openchain.h"
00004 #include "CollisionDetectors\CD_Vcollide.h"
00005 #include "geometry\Facet.h"
00006 #include "geometry\ObjectGroup.h"
00007 #include "Kinematics\LinkBase.h"
00008 #include "Universe/universe.h"
00009 #include "geometry\geo_rangesensor\Range_Sensor.h"
00010
00011
00012
00013
00014
00015 CD_Vcollide::CD_Vcollide (Universe& universe)
00016 :
00017 universePointer( NULL ),
00018 CollisionDetectorBase( universe ),
00019 CD_BasicStyle( universe ),
00020 CD_Linear( universe ),
00021 CD_LinearContinuous( universe ),
00022 vcollide( NULL )
00023 {
00024
00025 vcollide = new VCollide ;
00026
00027
00028 bool success = true ;
00029 for( int j = 0; j < entities.size(); j++ )
00030 {
00031 Entity* theEntity = entities[ j ] ;
00032 entities[ j ]->SetFrameManager( &theFrameManager ) ;
00033 success &= AddEntityToVcollide( entities[ j ] ) ;
00034 }
00035 CD_Bool::allGeometryUsed = success ;
00036
00037
00038 PermActivateAll() ;
00039 PermDeactivateFramesWithThemselves() ;
00040
00041
00042
00043
00044 std::vector< LinkBase* > links = universe.GetAllLinks();
00045 int i;
00046 int size = links.size();
00047 for( i = 0; i < size; i++ )
00048 {
00049 LinkBase* link = links[ i ];
00050 int baseframe = link->BaseFrameNum();
00051
00052 int j;
00053 int controlledSize = link->controlledFrames.size();
00054 for( j = 0; j < controlledSize; j++ )
00055 {
00056 int controlledFrame = link->controlledFrames[ j ];
00057 DeactivateFrames( baseframe, controlledFrame );
00058 }
00059 }
00060
00061
00062 }
00063
00064 CD_Vcollide::CD_Vcollide (const CD_Vcollide& right)
00065
00066 : universePointer(NULL)
00067
00068
00069 ,CollisionDetectorBase( right ),
00070 CD_BasicStyle( right ),
00071 CD_Linear( right ),
00072 CD_LinearContinuous( right ),
00073 vcollide( NULL )
00074
00075 {
00076
00077
00078
00079
00080
00081 vcollide = new VCollide ;
00082
00083 meshes.reserve( right.meshes.size() ) ;
00084 for( int i = 0; i < right.meshes.size(); i++ )
00085 {
00086 int numMeshes = meshes.size() ;
00087 Mesh* addMe = right.meshes[ i ] ;
00088 this->AddEntityToVcollide( addMe ) ;
00089
00090 }
00091
00092
00093 }
00094
00095
00096 CD_Vcollide::~CD_Vcollide()
00097 {
00098
00099 int i;
00100 for( i = 0; i < meshes.size(); i++ )
00101 {
00102 Mesh* deleteMe = meshes[ i ] ;
00103 delete deleteMe ;
00104 meshes[ i ] = NULL ;
00105 }
00106 meshes.clear() ;
00107
00108 for( i = 0; i < vcollideIndexes.size(); i++ )
00109 {
00110 vcollide->DeleteObject( vcollideIndexes[ i ] ) ;
00111 }
00112 vcollideIndexes.clear() ;
00113 dirtyElements.clear() ;
00114 for( i = 0; i < linkVcollide.size(); i++ )
00115 {
00116 linkVcollide[ i ].clear() ;
00117 }
00118 linkVcollide.clear() ;
00119
00120 delete vcollide ;
00121
00122 }
00123
00124
00125
00126
00127 CollisionDetectorBase* CD_Vcollide::Clone () const
00128 {
00129
00130 CD_Vcollide* newVC = new CD_Vcollide( *this ) ;
00131 CD_InterfaceToCollisionQueries* CDitc = dynamic_cast< CD_Bool* >( newVC ) ;
00132 CollisionDetectorBase* returnMe = dynamic_cast< CollisionDetectorBase* >( CDitc );
00133 return returnMe ;
00134
00135 }
00136
00137 bool CD_Vcollide::IsInterfering (const Configuration& config)
00138 {
00139
00140 CD_Bool::IncrementCallCount();
00141
00142 Semaphore semaphore( this->guid );
00143 semaphore.Lock();
00144 SetConfiguration( config ) ;
00145
00146
00147
00148
00149 for( int i = 0; i < meshes.size(); i++ )
00150 {
00151 const Mesh* mesh = meshes[ i ] ;
00152
00153 Matrix4x4 m1 = mesh->GetTransform() ;
00154
00155 int vcollideIndex = vcollideIndexes[ i ] ;
00156 assert( vcollideIndex >= 0 ) ;
00157
00158
00159 vcollide->UpdateTrans( vcollideIndex, m1.values ) ;
00160 }
00161
00162
00163
00164
00165 int success = vcollide->Collide() ;
00166 assert( success == VC_OK ) ;
00167 VCReportType vcrep ;
00168 int numCollisions = vcollide->Report( 1, &vcrep ) ;
00169 bool returnMe = false;
00170 if( numCollisions == 0 )
00171 {
00172 returnMe = false;
00173 }
00174 else
00175 {
00176 returnMe = true;
00177 }
00178 semaphore.Unlock();
00179 return returnMe;
00180
00181 }
00182
00183 bool CD_Vcollide::IsInterfering (const Frame &pose)
00184 {
00185 Semaphore semaphore( this->guid );
00186 semaphore.Lock();
00187
00188 int vcollideIndex = -1;
00189 for( int i = 0; i < meshes.size(); i++ )
00190 {
00191 if (meshes[ i ]->BaseFrame() == 1)
00192 {
00193 vcollideIndex = vcollideIndexes[ i ] ;
00194 break;
00195 }
00196 }
00197
00198 assert( vcollideIndex != -1 );
00199 if (vcollideIndex == -1)
00200 return false;
00201
00202 Matrix4x4 m1;
00203 m1.SetValues(pose);
00204 vcollide->UpdateTrans( vcollideIndex, m1.values ) ;
00205
00206 int success = vcollide->Collide() ;
00207 assert( success == VC_OK ) ;
00208 VCReportType vcrep ;
00209 int numCollisions = vcollide->Report( 1, &vcrep ) ;
00210 bool returnMe = false;
00211 if( numCollisions == 0 )
00212 {
00213 returnMe = false;
00214 }
00215 else
00216 {
00217 returnMe = true;
00218 }
00219 semaphore.Unlock();
00220 return returnMe;
00221 }
00222
00223 bool CD_Vcollide::AddEntityToVcollide (const Entity* entity)
00224 {
00225
00226
00227
00228
00229 int size = linkVcollide.size() ;
00230 int baseFrame = entity->BaseFrame() ;
00231 while( linkVcollide.size() < baseFrame + 1 )
00232 {
00233 std::set< unsigned int > setOfVcollideMeshes ;
00234 linkVcollide.push_back( setOfVcollideMeshes );
00235 }
00236
00237 const Mesh* mesh = dynamic_cast< const Mesh* >( entity ) ;
00238 if( mesh != NULL )
00239 {
00240 int vcollideIndex = AddMeshToVcollide( *mesh ) ;
00241 return true ;
00242 }
00243 const ObjectGroup* group = dynamic_cast< const ObjectGroup* >( entity ) ;
00244 if( group != NULL )
00245 {
00246 bool returnMe = true ;
00247 for( int i = 0; i < group->Size(); i++ )
00248 {
00249 const ObjectBase* addme = ( *group )[ i ] ;
00250 returnMe &= AddEntityToVcollide( addme ) ;
00251 }
00252 return returnMe ;
00253 }
00254
00255 const R_OpenChain* rOpenChain = dynamic_cast< const R_OpenChain* >( entity ) ;
00256 if( rOpenChain != NULL )
00257 {
00258
00259 return true ;
00260 }
00261
00262 const Range_Sensor* camera = dynamic_cast< const Range_Sensor* >( entity ) ;
00263 if( camera != NULL )
00264 {
00265
00266 return true ;
00267 }
00268
00269 return false ;
00270
00271 }
00272
00273 int CD_Vcollide::AddMeshToVcollide (const Mesh& mesh)
00274 {
00275
00276
00277
00278 Mesh* addMe = dynamic_cast< Mesh*>( mesh.Clone() ) ;
00279 meshes.push_back( addMe ) ;
00280
00281
00282 int vcollideIndex = -1 ;
00283 int success = vcollide->NewObject( &vcollideIndex );
00284 assert( success == VC_OK ) ;
00285
00286
00287 int size = mesh.GetFacets().size();
00288 int i;
00289 for( i = 0; i < size; ++i )
00290 {
00291 Facet face = mesh.GetFacets()[ i ] ;
00292 int edges = face.vertexNumbers.size() ;
00293 assert( edges == 3 ) ;
00294 double v1[ 3 ] ;
00295 double v2[ 3 ] ;
00296 double v3[ 3 ] ;
00297
00298
00299 for( int j = 0; j < 3; j++ )
00300 {
00301 int meshSize = mesh.GetVertexes().size() ;
00302 int faceSize = face.vertexNumbers.size() ;
00303
00304 v1[ j ] = mesh.GetVertexes()[ face.vertexNumbers[ 0 ] ][ j ] ;
00305 v2[ j ] = mesh.GetVertexes()[ face.vertexNumbers[ 1 ] ][ j ] ;
00306 v3[ j ] = mesh.GetVertexes()[ face.vertexNumbers[ 2 ] ][ j ] ;
00307 }
00308 vcollide->AddTri( v1, v2, v3 ) ;
00309 }
00310
00311
00312 success = vcollide->EndObject() ;
00313 if( success == VC_ERR_EMPTY_OBJECT )
00314 {
00315 assert( false ) ;
00316 }
00317 assert( success == VC_OK ) ;
00318
00319
00320 int baseFrame = mesh.BaseFrame() ;
00321
00322 std::set< unsigned int > theSet = linkVcollide[ baseFrame ] ;
00323 theSet.insert( vcollideIndex ) ;
00324 linkVcollide[ baseFrame ] = theSet ;
00325 size = theSet.size() ;
00326 size = linkVcollide[ baseFrame ].size() ;
00327
00328 vcollideIndexes.push_back( vcollideIndex ) ;
00329 return vcollideIndex ;
00330
00331 }
00332
00333 void CD_Vcollide::DeactivateFrames (const unsigned int frame1, const unsigned int frame2)
00334 {
00335
00336 if( frame2 > frame1 )
00337 {
00338 DeactivateFrames( frame2, frame1 ) ;
00339 return ;
00340 }
00341 CD_BasicStyle::DeactivateFrames( frame1, frame2 ) ;
00342 int lSize = linkVcollide.size() ;
00343
00344
00345 if( lSize <= frame1 )
00346 {
00347 return ;
00348 }
00349 if( lSize <= frame2 )
00350 {
00351 return ;
00352 }
00353
00354 int size1 = linkVcollide[ frame1 ].size() ;
00355 std::set< unsigned int >::iterator i1 ;
00356 std::set< unsigned int >::iterator i2 ;
00357
00358 for( i1 = linkVcollide[ frame1 ].begin(); i1 != linkVcollide[ frame1 ].end() ; i1++ )
00359 {
00360 int index1 = *i1 ;
00361 for( i2 = linkVcollide[ frame2 ].begin(); i2 != linkVcollide[ frame2 ].end(); i2++ )
00362 {
00363 int index2 = *i2 ;
00364 if( index1 != index2 )
00365 {
00366 int success = vcollide->DeactivatePair( index1, index2 ) ;
00367 success &= vcollide->DeactivatePair( index2, index1 ) ;
00368 assert( success == 1 ) ;
00369 }
00370 }
00371 }
00372
00373 }
00374
00375 void CD_Vcollide::UpdateMovedLink (const unsigned int linkNum) const
00376 {
00377
00378
00379 links[ linkNum ]->UpdateFrames() ;
00380
00381 }
00382
00383 void CD_Vcollide::ActivateFrames (const unsigned int frame1, const unsigned int frame2)
00384 {
00385
00386 if( !FramePairPermEnabled( frame1, frame2 ) )
00387 {
00388 return ;
00389 }
00390
00391 if( frame2 > frame1 )
00392 {
00393 ActivateFrames( frame2, frame1 ) ;
00394 return ;
00395 }
00396
00397 CD_BasicStyle::ActivateFrames( frame1, frame2 ) ;
00398 int lSize = linkVcollide.size() ;
00399
00400
00401 if( lSize <= frame1 )
00402 {
00403 return ;
00404 }
00405 if( lSize <= frame2 )
00406 {
00407 return ;
00408 }
00409
00410 int size1 = linkVcollide[ frame1 ].size() ;
00411 std::set< unsigned int >::iterator i1 ;
00412 std::set< unsigned int >::iterator i2 ;
00413
00414 int geometriesInFrame1 = linkVcollide[ frame1 ].size() ;
00415 int geometriesInFrame2 = linkVcollide[ frame2 ].size() ;
00416
00417 for( i1 = linkVcollide[ frame1 ].begin(); i1 != linkVcollide[ frame1 ].end() ; i1++ )
00418 {
00419 int index1 = *i1 ;
00420 for( i2 = linkVcollide[ frame2 ].begin(); i2 != linkVcollide[ frame2 ].end(); i2++ )
00421 {
00422 int index2 = *i2 ;
00423 if( index1 != index2 )
00424 {
00425 vcollide->ActivatePair( index1, index2 ) ;
00426 vcollide->ActivatePair( index2, index1 ) ;
00427
00428 }
00429 }
00430 }
00431
00432 }
00433
00434
00435
00436
00437
00438
00439