Files
EgtGeomKernel/CDeRectPrismoidClosedSurfTm.cpp
T
DarioS 2d8c815032 EgtGeomKernel 2.5e3 :
- a BBox3d aggiunto 2° metodo Overlaps con box aventi diverso orientamento
- nelle funzioni di Collision Detection migliorato controllo non interne
- nele funzioni Avoid di Zmap si utilizza confronto box con diverso orientamento.
2023-05-14 11:58:48 +02:00

73 lines
3.5 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2020-2020
//----------------------------------------------------------------------------
// File : CDePyramidClosedSurfTm.h Data : 09.11.20 Versione :
// Contenuto : Implementazione funzione verifica collisione tra
// Prismoide a basi rettangolari e Closed SurfTriMesh.
//
// Modifiche : 09.11.20 LM Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "CDeRectPrismoidTria.h"
#include "/EgtDev/Include/EGkCDeRectPrismoidClosedSurfTm.h"
#include "/EgtDev/Include/EGkDistPointSurfTm.h"
using namespace std ;
//----------------------------------------------------------------------------
// Il sistema di riferimento deve avere l'origine nel centro della Base, asse X lungo
// un segmento della stessa e asse Z ortogonale alle basi e diretta verso la base Top.
// Il sistema di riferimento della piramide deve essere immerso in quello della superficie.
bool
CDeRectPrismoidClosedSurfTm( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
double dLenghtTopX, double dLenghtTopY, double dHeight,
double dSafeDist, const ISurfTriMesh& Stm)
{
// Se il tronco di piramide non è definito o la superficie non ben definita non ha senso proseguire.
if ( max( dLenghtBaseX, dLenghtTopX) < EPS_SMALL ||
max( dLenghtBaseY, dLenghtTopY) < EPS_SMALL ||
dHeight < EPS_SMALL || ! Stm.IsValid())
return false ;
// 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,
dSafeDist, trTria))
return true ;
}
}
// Se superficie aperta, non c'è collisione
if ( ! Stm.IsClosed())
return false ;
// Se il BBox del tronco di piramide non è interno a quello del poliedro e viceversa, non c'è collisione
if ( ! b3Surf.Encloses( b3Pyr) && ! b3Pyr.Encloses( b3Surf))
return false ;
// Verifico se il tronco di piramide è dentro la superficie tramite calcolo distanza minima del suo centro
Point3d ptPyrCen( 0, 0, dHeight / 2) ;
ptPyrCen.ToGlob( frPrismoid) ;
DistPointSurfTm DistPyrCenSurfCalc( ptPyrCen, Stm) ;
// C'è collisione se il tronco di piramide è interno
return ( DistPyrCenSurfCalc.IsPointInside()) ;
}