diff --git a/CDBoxPolyhedron.cpp b/CDBoxPolyhedron.cpp new file mode 100644 index 0000000..d06305d --- /dev/null +++ b/CDBoxPolyhedron.cpp @@ -0,0 +1,44 @@ +//---------------------------------------------------------------------------- +// EgalTech 2016-2016 +//---------------------------------------------------------------------------- +// File : CDBoxPolyhedron.cpp Data : 05.10.16 Versione : 1.6v1 +// Contenuto : Implementazione della verifica di collisione tra +// BoundingBox e Polyhedron. +// +// +// Modifiche : 05.10.16 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "/EgtDev/Include/EGkCDBoxTria.h" +#include "/EgtDev/Include/EGkCDBoxPolyhedron.h" + +using namespace std ; + +//---------------------------------------------------------------------------- +bool +CDBoxPolyhedron( const BBox3d& b3Box, const ISurfTriMesh& Stm) +{ + // verifico che la trimesh sia effettivamente un poliedro + if ( ! Stm.IsClosed()) + return false ; + // recupero BBox del poliedro + BBox3d b3Poly ; + if ( ! Stm.GetLocalBBox( b3Poly)) + return false ; + // confronto i due Box + if ( ! b3Box.Overlaps( b3Poly)) + return false ; + // confronto il Box con tutti i triangoli + Triangle3d Tria ; + int nId = Stm.GetFirstTriangle( Tria) ; + while ( nId != SVT_NULL) { + if ( CDBoxTria( b3Box, Tria)) + return true ; + nId = Stm.GetNextTriangle( nId, Tria) ; + } + return false ; +} diff --git a/CDBoxTria.cpp b/CDBoxTria.cpp new file mode 100644 index 0000000..6fe1ecf --- /dev/null +++ b/CDBoxTria.cpp @@ -0,0 +1,154 @@ +//---------------------------------------------------------------------------- +// EgalTech 2016-2016 +//---------------------------------------------------------------------------- +// File : CDBoxTria.cpp Data : 05.10.16 Versione : 1.6v1 +// Contenuto : Implementazione della verifica di collisione tra +// BoundingBox e Triangle3d. +// +// +// Modifiche : 05.10.16 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "/EgtDev/Include/EGkCDBoxTria.h" +#include "/EgtDev/Include/EGkPlane3d.h" + +using namespace std ; + +//-------------------------------------------------------------------------------- +static bool +CDBoxPlane( const BBox3d& Box, const Plane3d& Plane) +{ + // vedi Ericson, Real-Time Collision Detection, pag. 164 + + // Compute box center and extents + Point3d ptCen ; + Vector3d vtExt ; + if ( ! Box.GetCenterExtent( ptCen, vtExt)) + return false ; + + // Compute the projection interval radius of b onto L(t) = ptCen + t * Plane.vtN + double dR = vtExt.x * abs( Plane.vtN.x) + + vtExt.y * abs( Plane.vtN.y) + + vtExt.z * abs( Plane.vtN.z) ; + + // Compute distance of box center from plane + double dS = ( ptCen - ORIG) * Plane.vtN - Plane.dDist ; + + // Intersection occurs when distance dS falls within [-dR,+dR] interval + return ( abs( dS) < dR + EPS_SMALL) ; +} + +//-------------------- Macro for X-tests ------------------------------------- +#define AXISTEST_X01( a, b, fa, fb) \ + p0 = a * ptV0.y - b * ptV0.z ; \ + p2 = a * ptV2.y - b * ptV2.z ; \ + if ( p0 < p2) { dMin = p0 ; dMax = p2 ; } else { dMin = p2 ; dMax = p0 ; } \ + rad = fa * vtExt.y + fb * vtExt.z ; \ + if ( dMin > rad + EPS_SMALL || dMax < - rad - EPS_SMALL) return false ; + +#define AXISTEST_X2( a, b, fa, fb) \ + p0 = a * ptV0.y - b * ptV0.z ; \ + p1 = a * ptV1.y - b * ptV1.z ; \ + if ( p0 < p1) { dMin = p0 ; dMax = p1 ; } else { dMin = p1 ; dMax = p0 ; } \ + rad = fa * vtExt.y + fb * vtExt.z ; \ + if ( dMin > rad + EPS_SMALL || dMax < -rad - EPS_SMALL) return false ; + +//-------------------- Macro for Y-tests ------------------------------------- +#define AXISTEST_Y02( a, b, fa, fb) \ + p0 = - a * ptV0.x + b * ptV0.z ; \ + p2 = - a * ptV2.x + b * ptV2.z ; \ + if ( p0 < p2) { dMin = p0 ; dMax = p2 ; } else { dMin = p2 ; dMax = p0 ; } \ + rad = fa * vtExt.x + fb * vtExt.z ; \ + if ( dMin > rad + EPS_SMALL || dMax < -rad - EPS_SMALL) return false ; + +#define AXISTEST_Y1( a, b, fa, fb) \ + p0 = - a * ptV0.x + b * ptV0.z ; \ + p1 = - a * ptV1.x + b * ptV1.z ; \ + if ( p0 < p1) { dMin = p0 ; dMax = p1 ; } else { dMin = p1 ; dMax = p0 ; } \ + rad = fa * vtExt.x + fb * vtExt.z ; \ + if ( dMin > rad + EPS_SMALL || dMax < -rad - EPS_SMALL) return false ; + +//-------------------- Macro for Z-tests ------------------------------------- +#define AXISTEST_Z12( a, b, fa, fb) \ + p1 = a * ptV1.x - b * ptV1.y ; \ + p2 = a * ptV2.x - b * ptV2.y ; \ + if ( p2 < p1) { dMin = p2 ; dMax = p1 ; } else { dMin = p1 ; dMax = p2 ; } \ + rad = fa * vtExt.x + fb * vtExt.y ; \ + if ( dMin > rad + EPS_SMALL || dMax < -rad - EPS_SMALL) return false ; + +#define AXISTEST_Z0( a, b, fa, fb) \ + p0 = a * ptV0.x - b * ptV0.y ; \ + p1 = a * ptV1.x - b * ptV1.y ; \ + if ( p0 < p1) { dMin = p0 ; dMax = p1 ; } else { dMin = p1 ; dMax = p0 ; } \ + rad = fa * vtExt.x + fb * vtExt.y ; \ + if ( dMin > rad + EPS_SMALL || dMax < -rad - EPS_SMALL) return false ; + + +//---------------------------------------------------------------------------- +bool +CDBoxTria( const BBox3d& b3Box, const Triangle3d& trTria) +{ + // vedi Ericson, Real-Time Collision Detection, pag. 172 + Akenine-Moller + + // Compute box center and extents + Point3d ptCen ; + Vector3d vtExt ; + if ( ! b3Box.GetCenterExtent( ptCen, vtExt)) + return false ; + + // Translate triangle as conceptually moving AABB to origin + Point3d ptV0 = trTria.GetP( 0) - ( ptCen - ORIG) ; + Point3d ptV1 = trTria.GetP( 1) - ( ptCen - ORIG) ; + Point3d ptV2 = trTria.GetP( 2) - ( ptCen - ORIG) ; + + // Compute edge vectors for triangle + Vector3d vtE0 = ptV1 - ptV0 ; + Vector3d vtE1 = ptV2 - ptV1 ; + Vector3d vtE2 = ptV0 - ptV2 ; + + // Test axes a00..a22 (category 3) + double dMin, dMax, p0, p1, p2, rad, fex, fey, fez ; + + fex = abs( vtE0.x) ; + fey = abs( vtE0.y) ; + fez = abs( vtE0.z) ; + AXISTEST_X01( vtE0.z, vtE0.y, fez, fey) + AXISTEST_Y02( vtE0.z, vtE0.x, fez, fex) + AXISTEST_Z12( vtE0.y, vtE0.x, fey, fex) + + fex = abs( vtE1.x) ; + fey = abs( vtE1.y) ; + fez = abs( vtE1.z) ; + AXISTEST_X01( vtE1.z, vtE1.y, fez, fey) + AXISTEST_Y02( vtE1.z, vtE1.x, fez, fex) + AXISTEST_Z0( vtE1.y, vtE1.x, fey, fex) + + fex = abs( vtE2.x) ; + fey = abs( vtE2.y) ; + fez = abs( vtE2.z) ; + AXISTEST_X2( vtE2.z, vtE2.y, fez, fey) + AXISTEST_Y1( vtE2.z, vtE2.x, fez, fex) + AXISTEST_Z12( vtE2.y, vtE2.x, fey, fex) + + // Test the three axes corresponding to the face normals of AABB Box (category 1). + // Exit if... + // ... [-e0, e0] and [min(v0.x,v1.x,v2.x), max(v0.x,v1.x,v2.x)] do not overlap + if ( max( ptV0.x, max( ptV1.x, ptV2.x)) < - vtExt.x || min( ptV0.x, min( ptV1.x, ptV2.x)) > vtExt.x) + return false ; + // ... [-e1, e1] and [min(v0.y,v1.y,v2.y), max(v0.y,v1.y,v2.y)] do not overlap + if ( max( ptV0.y, max( ptV1.y, ptV2.y)) < - vtExt.y || min( ptV0.y, min( ptV1.y, ptV2.y)) > vtExt.y) + return false ; + // ... [-e2, e2] and [min(v0.z,v1.z,v2.z), max(v0.z,v1.z,v2.z)] do not overlap + if ( max( ptV0.z, max( ptV1.z, ptV2.z)) < - vtExt.z || min( ptV0.z, min( ptV1.z, ptV2.z)) > vtExt.z) + return false ; + + // Test separating axis corresponding to triangle face normal (category 2) + Plane3d Plane ; + Plane.vtN = trTria.GetN() ; + Plane.dDist = Plane.vtN * ( trTria.GetP( 0) - ORIG) ; + return CDBoxPlane( b3Box, Plane) ; +} diff --git a/Simple CDSurfFrMove.cpp b/CDSimpleSurfFrMove.cpp similarity index 94% rename from Simple CDSurfFrMove.cpp rename to CDSimpleSurfFrMove.cpp index 986ee10..1f42674 100644 --- a/Simple CDSurfFrMove.cpp +++ b/CDSimpleSurfFrMove.cpp @@ -1,7 +1,7 @@ //---------------------------------------------------------------------------- // EgalTech 2015-2016 //---------------------------------------------------------------------------- -// File : SimpleCDSurfFrMove.cpp Data : 10.01.16 Versione : 1.6l7 +// File : CDSimpleSurfFrMove.cpp Data : 10.01.16 Versione : 1.6l7 // Contenuto : Implementazione delle funzioni di movimento per SurfFlatRegion // senza collisione con altri oggetti dello stesso tipo e nello // stesso piano o in piani paralleli. @@ -14,22 +14,22 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" -#include "SimpleCDSurfFrMove.h" +#include "CDSimpleSurfFrMove.h" #include "SurfFlatRegion.h" #include "CurveLine.h" #include "CurveArc.h" #include "CurveComposite.h" #include "IntersLineArc.h" #include "GeoConst.h" -#include "/EgtDev/Include/EGkSimpleCDSurfFrMove.h" +#include "/EgtDev/Include/EGkCDSimpleSurfFrMove.h" #include "/EgtDev/Include/EgtPointerOwner.h" using namespace std ; //---------------------------------------------------------------------------- -// SimpleCDSurfFrMove +// CDSimpleSurfFrMove //---------------------------------------------------------------------------- -SimpleCDSurfFrMove::SimpleCDSurfFrMove( const ISurfFlatRegion& SfrM, const ISurfFlatRegion& SfrF) +CDSimpleSurfFrMove::CDSimpleSurfFrMove( const ISurfFlatRegion& SfrM, const ISurfFlatRegion& SfrF) { // salvo puntatori alle regioni m_pRegM = &SfrM ; @@ -38,9 +38,9 @@ SimpleCDSurfFrMove::SimpleCDSurfFrMove( const ISurfFlatRegion& SfrM, const ISurf //---------------------------------------------------------------------------- bool -SimpleCDSurfFrMove::Translate( const Vector3d& vtDir, double& dLen) +CDSimpleSurfFrMove::Translate( const Vector3d& vtDir, double& dLen) { - MySimpleCDSurfFrMove ScdMove ( *m_pRegM, *m_pRegF) ; + MyCDSimpleSurfFrMove ScdMove ( *m_pRegM, *m_pRegF) ; m_SCollInfo.nType = SCI_NONE ; if ( ! ScdMove.Translate( vtDir, dLen)) return false ; @@ -50,18 +50,18 @@ SimpleCDSurfFrMove::Translate( const Vector3d& vtDir, double& dLen) //---------------------------------------------------------------------------- bool -SimpleCDSurfFrMove::Rotate( const Point3d& ptCen, double& dAng) +CDSimpleSurfFrMove::Rotate( const Point3d& ptCen, double& dAng) { - MySimpleCDSurfFrMove ScdMove ( *m_pRegM, *m_pRegF) ; + MyCDSimpleSurfFrMove ScdMove ( *m_pRegM, *m_pRegF) ; m_SCollInfo.nType = SCI_NONE ; return ScdMove.Rotate( ptCen, dAng) ; } //---------------------------------------------------------------------------- -// MySimpleCDSurfFrMove +// MyCDSimpleSurfFrMove //---------------------------------------------------------------------------- -MySimpleCDSurfFrMove::MySimpleCDSurfFrMove( const ISurfFlatRegion& SfrM, const ISurfFlatRegion& SfrF) +MyCDSimpleSurfFrMove::MyCDSimpleSurfFrMove( const ISurfFlatRegion& SfrM, const ISurfFlatRegion& SfrF) { // recupero rappresentazione base della regione mobile m_pRegM = GetBasicSurfFlatRegion( &SfrM) ; @@ -77,7 +77,7 @@ MySimpleCDSurfFrMove::MySimpleCDSurfFrMove( const ISurfFlatRegion& SfrM, const I //---------------------------------------------------------------------------- bool -MySimpleCDSurfFrMove::Translate( const Vector3d& vtDir, double& dLen) +MyCDSimpleSurfFrMove::Translate( const Vector3d& vtDir, double& dLen) { // verifico validità regioni if ( m_pRegM == nullptr || m_pRegF == nullptr) @@ -179,7 +179,7 @@ MySimpleCDSurfFrMove::Translate( const Vector3d& vtDir, double& dLen) //---------------------------------------------------------------------------- bool -MySimpleCDSurfFrMove::Rotate( const Point3d& ptCen, double& dAng) +MyCDSimpleSurfFrMove::Rotate( const Point3d& ptCen, double& dAng) { // verifico validità regioni if ( m_pRegM == nullptr || m_pRegF == nullptr) @@ -250,7 +250,7 @@ MySimpleCDSurfFrMove::Rotate( const Point3d& ptCen, double& dAng) // Massima traslazione da posizione sicura in direzione e con limite dati //---------------------------------------------------------------------------- bool -MySimpleCDSurfFrMove::TranslateCurveNoCollisionCurve( const ICurve* pCrv1, const ICurve* pCrv2, +MyCDSimpleSurfFrMove::TranslateCurveNoCollisionCurve( const ICurve* pCrv1, const ICurve* pCrv2, const Vector3d& vtDir, double& dLen, SCollInfo& scInfo) { // se entrambe linee, procedo direttamente @@ -308,7 +308,7 @@ MySimpleCDSurfFrMove::TranslateCurveNoCollisionCurve( const ICurve* pCrv1, const // Massima traslazione da posizione sicura in direzione e con limite dati //---------------------------------------------------------------------------- bool -MySimpleCDSurfFrMove::TranslateLineNoCollisionLine( const CurveLine* pLine1, const CurveLine* pLine2, +MyCDSimpleSurfFrMove::TranslateLineNoCollisionLine( const CurveLine* pLine1, const CurveLine* pLine2, const Vector3d& vtDir, double& dLen, SCollInfo& scInfo) { // versore ortogonale al movimento @@ -422,7 +422,7 @@ MySimpleCDSurfFrMove::TranslateLineNoCollisionLine( const CurveLine* pLine1, con // Massima rotazione da posizione sicura in direzione e con limite dati //---------------------------------------------------------------------------- bool -MySimpleCDSurfFrMove::RotateCurveNoCollisionCurve( const ICurve* pCrv1, const ICurve* pCrv2, +MyCDSimpleSurfFrMove::RotateCurveNoCollisionCurve( const ICurve* pCrv1, const ICurve* pCrv2, const Point3d& ptCen, double& dAng) { // se entrambe linee, procedo direttamente @@ -470,7 +470,7 @@ MySimpleCDSurfFrMove::RotateCurveNoCollisionCurve( const ICurve* pCrv1, const IC // Massima rotazione da posizione sicura in direzione e con limite dati //---------------------------------------------------------------------------- bool -MySimpleCDSurfFrMove::RotateLineNoCollisionLine( const CurveLine* pLine1, const CurveLine* pLine2, +MyCDSimpleSurfFrMove::RotateLineNoCollisionLine( const CurveLine* pLine1, const CurveLine* pLine2, const Point3d& ptCen, double& dAng) { // senso di rotazione diff --git a/SimpleCDSurfFrMove.h b/CDSimpleSurfFrMove.h similarity index 87% rename from SimpleCDSurfFrMove.h rename to CDSimpleSurfFrMove.h index 1a4cc88..d05f19f 100644 --- a/SimpleCDSurfFrMove.h +++ b/CDSimpleSurfFrMove.h @@ -1,7 +1,7 @@ //---------------------------------------------------------------------------- // EgalTech 2015-2016 //---------------------------------------------------------------------------- -// File : SimpleCDSurfFrMove.h Data : 10.01.16 Versione : 1.6l7 +// File : CDSimpleSurfFrMove.h Data : 10.01.16 Versione : 1.6l7 // Contenuto : Dich.ne classe privata per movimento di superfici flat region // nel loro piano con semplice verifica di collisione // (ovvero controllando solo gli esterni). @@ -13,16 +13,16 @@ #pragma once -#include "/EgtDev/Include/EGkSimpleCDSurfFrMove.h" +#include "/EgtDev/Include/EGkCDSimpleSurfFrMove.h" class CurveLine ; class SurfFlatRegion ; //---------------------------------------------------------------------------- -class MySimpleCDSurfFrMove +class MyCDSimpleSurfFrMove { public : - MySimpleCDSurfFrMove( const ISurfFlatRegion& SfrM, const ISurfFlatRegion& SfrF) ; + MyCDSimpleSurfFrMove( const ISurfFlatRegion& SfrM, const ISurfFlatRegion& SfrF) ; public : bool Translate( const Vector3d& vtDir, double& dLen) ; diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 55e588c..400f3e8 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj index 8a8b939..fae18f7 100644 --- a/EgtGeomKernel.vcxproj +++ b/EgtGeomKernel.vcxproj @@ -258,6 +258,8 @@ copy $(TargetPath) \EgtProg\Dll64 + + @@ -327,7 +329,7 @@ copy $(TargetPath) \EgtProg\Dll64 - + @@ -363,6 +365,9 @@ copy $(TargetPath) \EgtProg\Dll64 + + + @@ -408,7 +413,6 @@ copy $(TargetPath) \EgtProg\Dll64 - diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index ccbe36b..fea1dea 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -327,12 +327,18 @@ File di origine\GeoInters - - File di origine\GeoCollision - File di origine\GeoOffset + + File di origine\GeoCollision + + + File di origine\GeoCollision + + + File di origine\GeoCollision + @@ -737,10 +743,16 @@ File di intestazione - + File di intestazione\Include - + + File di intestazione\Include + + + File di intestazione\Include + + File di intestazione\Include diff --git a/SurfFlatRegion.h b/SurfFlatRegion.h index 892ab75..d23d332 100644 --- a/SurfFlatRegion.h +++ b/SurfFlatRegion.h @@ -106,7 +106,7 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW LOG_ERROR( GetEGkLogger(), "SurfFlatRegion : copy error") return *this ; } - friend class MySimpleCDSurfFrMove ; + friend class MyCDSimpleSurfFrMove ; private : enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;