diff --git a/CDeBoxClosedSurfTm.cpp b/CDeBoxClosedSurfTm.cpp index 1c9df9e..95f1ba5 100644 --- a/CDeBoxClosedSurfTm.cpp +++ b/CDeBoxClosedSurfTm.cpp @@ -1,13 +1,14 @@ //---------------------------------------------------------------------------- -// EgalTech 2016-2020 +// EgalTech 2016-2024 //---------------------------------------------------------------------------- -// File : CDBoxSurfTm.cpp Data : 09.01.20 Versione : 2.2a2 +// File : CDeBoxClosedSurfTm.cpp Data : 24.03.24 Versione : 2.6c2 // Contenuto : Implementazione della verifica di collisione tra // BoundingBox e Closed SurftriMesh. // // // Modifiche : 05.10.16 DS Creazione modulo. // 09.01.20 DS Cambio nome alla funzione. +// 24.03.24 DS Aggiunta TestCylSurfTm. // //---------------------------------------------------------------------------- @@ -66,3 +67,39 @@ CDeBoxClosedSurfTm( const Frame3d& frBox, const Vector3d& vtDiag, const ISurfTri // Se il box è interno c'è collisione return DistBoxCenSurfCalc.IsPointInside() ; } + +//---------------------------------------------------------------------------- +// Verifica l'interferenza tra il box e la superficie : restituisce true in caso di interferenza. +//---------------------------------------------------------------------------- +bool +TestBoxSurfTm( const Frame3d& frBox, const Vector3d& vtDiag, const ISurfTriMesh& Stm, double dSafeDist) +{ + // Se il box non è ben definito non ha senso proseguire + if ( vtDiag.IsSmall()) + return true ; + // Se superficie non valida, non ha senso proseguire + if ( ! Stm.IsValid()) + return true ; + // Recupero BBox del poliedro + BBox3d b3Poly = Stm.GetAllTriaBox() ; + // Calcolo il BBox del parallelepipedo + BBox3d b3BoxL( ORIG, ORIG + vtDiag) ; + if ( dSafeDist > EPS_SMALL) + b3BoxL.Expand( dSafeDist) ; + BBox3d b3Box = GetToGlob( b3BoxL, frBox) ; + // Se i BBox non interferiscono, non c'è collisione + if ( ! b3Poly.Overlaps( b3Box) || ! b3Poly.Overlaps( frBox, b3BoxL)) + return false ; + // Verifico se il parallelepipedo interferisce con i triangoli del poliedro presenti nel suo BBox + INTVECTOR vT ; + Stm.GetAllTriaOverlapBox( b3Box, vT) ; + for ( int nT : vT) { + Triangle3d Tria ; + if ( Stm.GetTriangle( nT, Tria)) { + if ( CDeBoxTria( frBox, vtDiag, Tria, dSafeDist)) + return true ; + } + } + // Non c'è interferenza + return false ; +} diff --git a/CDeClosedSurfTmClosedSurfTm.cpp b/CDeClosedSurfTmClosedSurfTm.cpp index b1d250c..dad76de 100644 --- a/CDeClosedSurfTmClosedSurfTm.cpp +++ b/CDeClosedSurfTmClosedSurfTm.cpp @@ -1,12 +1,12 @@ //---------------------------------------------------------------------------- -// EgalTech 2020-2020 +// EgalTech 2020-2024 //---------------------------------------------------------------------------- -// File : CDeSurfTmSurfTm.h Data : 14.06.23 Versione : 2.5f3 +// File : CDeClosedSurfTmClosedSurfTm.h Data : 24.03.24 Versione : 2.6c2 // Contenuto : Implementazione funzione verifica collisione tra // SurfTm e SurfTm. // // Modifiche : 13.11.20 LM Creazione modulo. -// +// 24.03.24 DS Aggiunta TestSurfTmSurfTm. // //---------------------------------------------------------------------------- @@ -122,3 +122,89 @@ CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& Surf DistPointSurfTm DistPoinBSrfA( ptPointB, *pSrfA) ; return ( DistPoinASrfB.IsPointInside() || DistPoinBSrfA.IsPointInside()) ; } + +//---------------------------------------------------------------------------- +// Verifica l'interferenza tra le due superfici : restituisce true in caso di interferenza. +//---------------------------------------------------------------------------- +bool +TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double dSafeDist) +{ + // Recupero le superfici base + const SurfTriMesh* pSrfA = GetBasicSurfTriMesh( &SurfA) ; + const SurfTriMesh* pSrfB = GetBasicSurfTriMesh( &SurfB) ; + // Se le superfici non sono valide, non ha senso proseguire + if ( pSrfA == nullptr || ! pSrfA->IsValid() || + pSrfB == nullptr || ! pSrfB->IsValid()) + return true ; + // Se i box delle superfici non si intersecano, ho finito. + BBox3d b3BoxA, b3BoxB ; + pSrfA->GetLocalBBox( b3BoxA) ; + pSrfB->GetLocalBBox( b3BoxB) ; + // Se è necessario, espando il box di B di una costante additiva pari alla distanza di sicurezza. + if ( dSafeDist > EPS_SMALL) + b3BoxB.Expand( dSafeDist) ; + // Se i box non si sovrappongono, non c'è collisione. Ho finito. + if ( ! b3BoxA.Overlaps( b3BoxB)) + return false ; + // Recupero i triangoli di A che interferiscono col box di B + INTVECTOR vTriaIndex ; + pSrfA->GetAllTriaOverlapBox( b3BoxB, vTriaIndex) ; + // Ciclo sui triangoli della superficie A che interferiscono col box della superficie B. + for ( int nTA : vTriaIndex) { + Triangle3d trTriaA ; + if ( ! ( pSrfA->GetTriangle( nTA, trTriaA) && trTriaA.Validate())) + continue ; + BBox3d b3BoxTriaA ; + trTriaA.GetLocalBBox( b3BoxTriaA) ; + // Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza. + if ( dSafeDist > EPS_SMALL) + b3BoxTriaA.Expand( dSafeDist) ; + // Recupero i triangoli di B che interferiscono col box del triangolo di A + INTVECTOR vNearTria ; + pSrfB->GetAllTriaOverlapBox( b3BoxTriaA, vNearTria) ; + // Settare tutti i triangoli come già processati. + // Al termine della chiamata i TempInt dei triangoli valgono 0. + pSrfB->ResetTempInts() ; + // Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A. + for ( int nTB : vNearTria) { + // Recupero il triangolo corrente della superficie B. + // Se triangolo non valido salto al successivo. + Triangle3d trTriaB ; + if ( ! ( pSrfB->GetTriangle( nTB, trTriaB) && trTriaB.Validate())) + continue ; + // Se necessario considero l'offset + if ( dSafeDist > EPS_SMALL) { + int nAdjTriaId[3] ; + pSrfB->GetTriangleAdjacencies( nTB, nAdjTriaId) ; + // Ciclo sui vertici del triangolo. + for ( int nVB = 0 ; nVB < 3 ; ++ nVB) { + // Se il triangolo adiacente al triangolo corrente su questo edge + // non è stato processato, processo il vertice e l'edge. + int nAdjTriaTempFlag ; + if ( ! ( pSrfB->GetTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0)) + continue ; + // Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito. + if ( CDeSimpleSpheTria( trTriaB.GetP( nVB), dSafeDist, trTriaA)) + return true ; + // Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito. + Vector3d vtEdgeV = trTriaB.GetP( ( nVB + 1) % 3) - trTriaB.GetP( nVB) ; + double dEdgeLen = vtEdgeV.Len() ; + vtEdgeV /= dEdgeLen ; + Frame3d frCyl ; + frCyl.Set( trTriaB.GetP( nVB), vtEdgeV) ; + if ( CDeSimpleCylTria( frCyl, dSafeDist, dEdgeLen, trTriaA)) + return true ; + } + // Traslo il triangolo + trTriaB.Translate( dSafeDist * trTriaB.GetN()) ; + } + // Processo il triangolo: se i due triangoli collidono ho finito. + if ( CDeTriaTria( trTriaA, trTriaB)) + return true ; + // Segno il triangolo come processato: nTemp = 1 + pSrfB->SetTempInt( nTB, 1) ; + } + } + // Non c'è interferenza + return false ; +} diff --git a/CDeConeFrustumClosedSurfTm.cpp b/CDeConeFrustumClosedSurfTm.cpp index 26e38a6..4d02952 100644 --- a/CDeConeFrustumClosedSurfTm.cpp +++ b/CDeConeFrustumClosedSurfTm.cpp @@ -1,12 +1,13 @@ //---------------------------------------------------------------------------- -// EgalTech 2020-2020 +// EgalTech 2020-2024 //---------------------------------------------------------------------------- -// File : CDCylSurfTm.cpp Data : 09.11.20 Versione : +// File : CDeConeFrustumClosedSurfTm.cpp Data : 24.031.24 Versione : 2.6c2 // Contenuto : Implementazione della verifica di collisione tra // Cone e Closed SurftriMesh. // // // Modifiche : 09.11.20 LM Creazione modulo. +// 24.03.24 DS Aggiunta TestConeFrustumSurfTm. // // //---------------------------------------------------------------------------- @@ -69,4 +70,44 @@ CDeConeFrustumClosedSurfTm( const Frame3d& frCone, double dBaseRad, double dTopR DistPointSurfTm DistConeCenSurfCalc( ptConeCen, Stm) ; // Se il tronco di cono è interno c'è collisione return DistConeCenSurfCalc.IsPointInside() ; -} \ No newline at end of file +} + +//---------------------------------------------------------------------------- +// Verifica l'interferenza tra il tronco di cono e la superficie : restituisce true in caso di interferenza. +//---------------------------------------------------------------------------- +bool +TestConeFrustumSurfTm( const Frame3d& frCone, double dBaseRad, double dTopRad, double dHeight, + const ISurfTriMesh& Stm, double dSafeDist) +{ + // Se il tronco di cono non è ben definito non ha senso proseguire + if ( max( dBaseRad, dTopRad) < EPS_SMALL || dHeight < EPS_SMALL) + return true ; + // Se superficie non valida, non ha senso proseguire + if ( ! Stm.IsValid()) + return true ; + // Recupero BBox della trimesh + BBox3d b3Surf = Stm.GetAllTriaBox() ; + // Calcolo il BBox del tronco di cono + double dMaxRad = max( dBaseRad, dTopRad) ; + BBox3d b3ConeL( Point3d( -dMaxRad, -dMaxRad, 0), + Point3d( dMaxRad, dMaxRad, dHeight)) ; + if ( dSafeDist > EPS_SMALL) + b3ConeL.Expand( dSafeDist) ; + BBox3d b3Cone = GetToGlob( b3ConeL, frCone) ; + // Se i BBox non interferiscono, non c'è collisione + if ( ! b3Surf.Overlaps( b3Cone) || ! b3Surf.Overlaps( frCone, b3ConeL)) + return false ; + // Recupero i triangoli che interferiscono con il box del cono + INTVECTOR vT ; + Stm.GetAllTriaOverlapBox( b3Cone, vT) ; + // Verifico se il tronco di cono interferisce con i triangoli del poliedro presenti nel suo BBox + for ( int nT : vT) { + Triangle3d trTria ; + if ( Stm.GetTriangle( nT, trTria)) { + if ( CDeConeFrustumTria( frCone, dBaseRad, dTopRad, dHeight, trTria, dSafeDist)) + return true ; + } + } + // Non c'è interferenza + return false ; +} diff --git a/CDeConeFrustumTria.h b/CDeConeFrustumTria.h index 80384c4..e9212cc 100644 --- a/CDeConeFrustumTria.h +++ b/CDeConeFrustumTria.h @@ -1,7 +1,7 @@ //---------------------------------------------------------------------------- // EgalTech 2020-2020 //---------------------------------------------------------------------------- -// File : CDeConTria.cpp Data : 28.10.20 Versione : 2.2k1 +// File : CDeConeFrustumTria.h Data : 28.10.20 Versione : 2.2k1 // Contenuto : Dichiarazione della verifica di collisione tra // Cone e Triangle3d. // diff --git a/CDeConvexTorusClosedSurfTm.cpp b/CDeConvexTorusClosedSurfTm.cpp index 84d7f14..38364b3 100644 --- a/CDeConvexTorusClosedSurfTm.cpp +++ b/CDeConvexTorusClosedSurfTm.cpp @@ -1,12 +1,12 @@ //---------------------------------------------------------------------------- -// EgalTech 2020-2020 +// EgalTech 2020-2024 //---------------------------------------------------------------------------- -// File : CDeConvexTorusTria.cpp Data : 18.11.20 Versione : +// File : CDeConvexTorusTria.cpp Data : 24.03.24 Versione : 2.6c2 // Contenuto : Implementazione funzione verifica collisione tra // toro convesso e SurfTriMesh. // // Modifiche : 18.11.20 LM Creazione modulo. -// +// 24.03.24 DS Aggiunta TestConvexTorusSurfTm. // //---------------------------------------------------------------------------- @@ -66,3 +66,42 @@ CDeConvexTorusClosedSurfTm( const Frame3d& frTorus, double dRad1, double dRad2, // Se il toro è interno c'è collisione return ( DistConeOrigSurfCalc.IsPointInside()) ; } + +//---------------------------------------------------------------------------- +// Verifica l'interferenza tra il toro convesso e la superficie : restituisce true in caso di interferenza +//---------------------------------------------------------------------------- +bool +TestConvexTorusSurfTm( const Frame3d& frTorus, double dRad1, double dRad2, + const ISurfTriMesh& Stm, double dSafeDist) +{ + // I raggi devono essere non nulli + if ( dRad1 < EPS_SMALL || dRad2 < EPS_SMALL) + return true ; + // Se superficie non valida, non ha senso proseguire + if ( ! Stm.IsValid()) + return true ; + // Box della superficie + BBox3d b3Surf = Stm.GetAllTriaBox() ; + // Box del toro (sempre completo) + BBox3d b3TorusL( Point3d( -dRad1 - dRad2, -dRad1 - dRad2, -dRad2), + Point3d( dRad1 + dRad2, dRad1 + dRad2, dRad2)) ; + if ( dSafeDist > EPS_SMALL) + b3TorusL.Expand( dSafeDist) ; + BBox3d b3Torus = GetToGlob( b3TorusL, frTorus) ; + // Se i BBox non interferiscono, non c'è collisione + if ( ! b3Surf.Overlaps( b3Torus) || ! b3Surf.Overlaps( frTorus, b3TorusL)) + return false ; + // Recupero i triangoli che interferiscono con il box del toro + INTVECTOR vT ; + Stm.GetAllTriaOverlapBox( b3Torus, vT) ; + // Verifico se il toro interferisce con i triangoli del poliedro presenti nel suo BBox + for ( int nT : vT) { + Triangle3d trTria ; + if ( Stm.GetTriangle( nT, trTria)) { + if ( CDeConvexTorusTria( frTorus, dRad1, dRad2, CT_TOT, trTria, dSafeDist)) + return true ; + } + } + // Non c'è interferenza + return false ; +} diff --git a/CDeCylClosedSurfTm.cpp b/CDeCylClosedSurfTm.cpp index e34e6d9..f61e1e9 100644 --- a/CDeCylClosedSurfTm.cpp +++ b/CDeCylClosedSurfTm.cpp @@ -1,13 +1,13 @@ //---------------------------------------------------------------------------- // EgalTech 2020-2024 //---------------------------------------------------------------------------- -// File : CDCylSurfTm.cpp Data : 15.02.24 Versione : 2.6b2 +// File : CDeCylClosedSurfTm.cpp Data : 24.03.24 Versione : 2.6c2 // Contenuto : Implementazione della verifica di collisione tra // Cylinder e Closed SurftriMesh. // // // Modifiche : 09.01.20 DS Creazione modulo. -// +// 24.03.24 DS Aggiunta TestCylSurfTm. // //---------------------------------------------------------------------------- @@ -73,3 +73,46 @@ CDeCylClosedSurfTm( const Frame3d& frCyl, double dR, double dH, const ISurfTriMe // Se il cilindro è interno c'è collisione return ( DistCylCenSurfCalc.IsPointInside()) ; } + +//---------------------------------------------------------------------------- +// Verifica l'interferenza tra il cilindro e la superficie : restituisce true in caso di interferenza +//---------------------------------------------------------------------------- +bool +TestCylSurfTm( const Frame3d& frCyl, double dR, double dH, const ISurfTriMesh& Stm, double dSafeDist) +{ + // Il cilindro deve essere ben definito + if ( dR < EPS_SMALL || dH < EPS_SMALL) + return true ; + // Se superficie non valida, non ha senso proseguire + if ( ! Stm.IsValid()) + return true ; + // Recupero BBox della superficie poligonale + BBox3d b3Poly = Stm.GetAllTriaBox() ; + // Sistemazioni cilindro + Frame3d frMyCyl = frCyl ; + if ( dH < 0) { + frMyCyl.Translate( dH * frMyCyl.VersZ()) ; + dH = -dH ; + } + // Calcolo il BBox del cilindro + BBox3d b3CylL( Point3d( -dR, -dR, 0), + Point3d( dR, dR, dH)) ; + if ( dSafeDist > EPS_SMALL) + b3CylL.Expand( dSafeDist) ; + BBox3d b3Cyl = GetToGlob( b3CylL, frMyCyl) ; + // Se i BBox non interferiscono, non c'è interferenza + if ( ! b3Poly.Overlaps( b3Cyl) || ! b3Poly.Overlaps( frMyCyl, b3CylL)) + return false ; + // Verifico se il cilindro interferisce con i triangoli del poliedro presenti nel suo BBox + INTVECTOR vT ; + Stm.GetAllTriaOverlapBox( b3Cyl, vT) ; + for ( int nT : vT) { + Triangle3d Tria ; + if ( Stm.GetTriangle( nT, Tria)) { + if ( CDeCylTria( frMyCyl, dR, dH, Tria, dSafeDist)) + return true ; + } + } + // Non c'è interferenza + return false ; +} diff --git a/CDeRectPrismoidClosedSurfTm.cpp b/CDeRectPrismoidClosedSurfTm.cpp index 05e9018..129e394 100644 --- a/CDeRectPrismoidClosedSurfTm.cpp +++ b/CDeRectPrismoidClosedSurfTm.cpp @@ -1,12 +1,12 @@ //---------------------------------------------------------------------------- -// EgalTech 2020-2020 +// EgalTech 2020-2024 //---------------------------------------------------------------------------- -// File : CDePyramidClosedSurfTm.h Data : 09.11.20 Versione : +// File : CDeRectPrismoidClosedSurfTm.h Data : 24.03.24 Versione : 2.6c2 // Contenuto : Implementazione funzione verifica collisione tra // Prismoide a basi rettangolari e Closed SurfTriMesh. // // Modifiche : 09.11.20 LM Creazione modulo. -// +// 24.03.24 DS Aggiunta TestRectPrismoidSurfTm. // //---------------------------------------------------------------------------- @@ -74,3 +74,48 @@ CDeRectPrismoidClosedSurfTm( const Frame3d& frPrismoid, double dLenghtBaseX, dou // C'è collisione se il tronco di piramide è interno return ( DistPyrCenSurfCalc.IsPointInside()) ; } + +//---------------------------------------------------------------------------- +// Verifica l'interferenza tra il Prismoide a basi rettangolari e la superficie : restituisce true in caso di interferenza. +//---------------------------------------------------------------------------- +bool +TestRectPrismoidSurfTm( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY, + double dLenghtTopX, double dLenghtTopY, double dHeight, + const ISurfTriMesh& Stm, double dSafeDist) +{ + // Se il tronco di piramide non è definito non ha senso proseguire. + if ( max( dLenghtBaseX, dLenghtTopX) < EPS_SMALL || + max( dLenghtBaseY, dLenghtTopY) < EPS_SMALL || + dHeight < EPS_SMALL) + return true ; + // Se superficie non valida, non ha senso proseguire + if ( ! Stm.IsValid()) + return true ; + // Recupero BBox della trimesh + BBox3d b3Surf = Stm.GetAllTriaBox() ; + // Calcolo il BBox del tronco di piramide + double dMaxLenX = max( dLenghtBaseX, dLenghtTopX) ; + double dMaxLenY = max( dLenghtBaseY, dLenghtTopY) ; + BBox3d b3PyrL( Point3d( -dMaxLenX / 2, -dMaxLenY / 2, 0.), + Point3d( dMaxLenX / 2, dMaxLenY / 2, dHeight)) ; + if ( dSafeDist > EPS_SMALL) + b3PyrL.Expand( dSafeDist) ; + BBox3d b3Pyr = GetToGlob( b3PyrL, frPrismoid) ; + // Se i BBox non interferiscono, non c'è collisione + if ( ! b3Surf.Overlaps( b3Pyr) || ! b3Surf.Overlaps( frPrismoid, b3PyrL)) + return false ; + // Recupero i triangoli che interferiscono con il box del tronco di piramide. + INTVECTOR vT ; + Stm.GetAllTriaOverlapBox( b3Pyr, vT) ; + // Verifico se il tronco di piramide interferisce con i triangoli del poliedro presenti nel suo BBox + for ( int nT : vT) { + Triangle3d trTria ; + if ( Stm.GetTriangle( nT, trTria)) { + if ( CDeRectPrismoidTria( frPrismoid, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY, dHeight, + trTria, dSafeDist)) + return true ; + } + } + // Non c'è interferenza + return false ; +} diff --git a/CDeSpheClosedSurfTm.cpp b/CDeSpheClosedSurfTm.cpp index ea4d103..8fd05f1 100644 --- a/CDeSpheClosedSurfTm.cpp +++ b/CDeSpheClosedSurfTm.cpp @@ -1,13 +1,13 @@ //---------------------------------------------------------------------------- -// EgalTech 2020-2020 +// EgalTech 2020-2024 //---------------------------------------------------------------------------- -// File : CDCylSurfTm.cpp Data : 09.01.20 Versione : 2.2a2 +// File : CDCylSurfTm.cpp Data : 24.03.24 Versione : 2.6c2 // Contenuto : Implementazione della verifica di collisione tra // Sphere e Closed SurftriMesh. // // // Modifiche : 09.01.20 DS Creazione modulo. -// +// 24.03.24 DS Aggiunta TestSpheSurfTm. // //---------------------------------------------------------------------------- @@ -60,3 +60,38 @@ CDeSpheClosedSurfTm( const Point3d& ptCen, double dR, const ISurfTriMesh& Stm, d // C'è collisione se la sfera è interna. return ( DistCenSurfCalc.IsPointInside()) ; } + +//---------------------------------------------------------------------------- +// Verifica l'interferenza tra la sfera e la superficie : restituisce true in caso di interferenza +//---------------------------------------------------------------------------- +bool +TestSpheSurfTm( const Point3d& ptCen, double dR, const ISurfTriMesh& Stm, double dSafeDist) +{ + // Il raggio deve essere non nullo + if ( dR < EPS_SMALL) + return true ; + // Se superficie non valida, non ha senso proseguire + if ( ! Stm.IsValid()) + return true ; + // Recupero BBox del poliedro + BBox3d b3Poly = Stm.GetAllTriaBox() ; + // Calcolo il BBox della sfera + BBox3d b3Sphe( ptCen, dR) ; + if ( dSafeDist > EPS_SMALL) + b3Sphe.Expand( dSafeDist) ; + // Se i BBox non interferiscono, non c'è collisione + if ( ! b3Sphe.Overlaps( b3Poly)) + return false ; + // Verifico se la sfera interferisce con i triangoli del poliedro presenti nel suo BBox + INTVECTOR vT ; + Stm.GetAllTriaOverlapBox( b3Sphe, vT) ; + for ( int nT : vT) { + Triangle3d Tria ; + if ( Stm.GetTriangle( nT, Tria)) { + if ( CDeSpheTria( ptCen, dR, Tria, dSafeDist)) + return true ; + } + } + // Non c'è interferenza + return false ; +}