3f2b6b2115
- aggiunte prime funzione per verifica collisione con oggetto capsule - piccoli aggiornamenti alle verifiche di collisione.
90 lines
3.4 KiB
C++
90 lines
3.4 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2022-2022
|
|
//----------------------------------------------------------------------------
|
|
// File : CDeCapsTria.cpp Data : 14.05.22 Versione : 2.4e2
|
|
// Contenuto : Implementazione della verifica di collisione tra
|
|
// Capsule (cilindro con estremità semisferiche) e Triangle3d.
|
|
//
|
|
//
|
|
// Modifiche :14.05.22 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "CDeCapsTria.h"
|
|
#include "CDeSpheTria.h"
|
|
#include "ProjPlane.h"
|
|
#include "/EgtDev/Include/EGkPolygon3d.h"
|
|
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
|
#include "/EgtDev/Include/EGkDistPointTria.h"
|
|
#include "/EgtDev/Include/EGkIntersLineSphere.h"
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
CDeSimpleCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, const Triangle3d& trTria)
|
|
{
|
|
// vedi Ericson, Real-Time Collision Detection, pag. 226 (Nettle method)
|
|
|
|
// Dati della capsule come sfera che si muove
|
|
Point3d ptC = ptP1 ;
|
|
Vector3d vtDir = ptP2 - ptP1 ;
|
|
double dLen = vtDir.Len() ;
|
|
if ( dLen < EPS_SMALL)
|
|
return CDeSimpleSpheTria( Media( ptP1, ptP2), dR, trTria) ;
|
|
vtDir /= dLen ;
|
|
if ( vtDir * trTria.GetN() > 0) {
|
|
vtDir.Invert() ;
|
|
ptC = ptP2 ;
|
|
}
|
|
// Determinazione primo possibile punto di contatto della sfera con il piano
|
|
Point3d ptD = ptC - trTria.GetN() * dR ;
|
|
// Intersezione della linea di movimento di questo punto con il piano del triangolo
|
|
Point3d ptP ;
|
|
int nLpRes = IntersLinePlane( ptD, vtDir, 1, trTria.GetPlane(), ptP, false) ;
|
|
// Se non c'è intersezione passante
|
|
if ( nLpRes != ILPT_YES) {
|
|
// se il centro dista dal piano non meno del raggio, allora non c'è sicuramente collisione
|
|
double dDist = DistPointPlane( ptP, trTria.GetPlane()) ;
|
|
if ( abs( dDist) >= dR)
|
|
return false ;
|
|
// !!! DA FARE !!!!
|
|
// si deve intersecare l'asse del capsule con i cilindri centrati sui lati del triangolo
|
|
// se intersezione inferiore a dLen allora collisione
|
|
// altrimenti si deve intersecare l'asse del capsule con le sfere centrate sui vertici del triangolo
|
|
// se intersezione inferiore a dLen allora collisione
|
|
// per ora salto
|
|
return false ;
|
|
}
|
|
// Determino la posizione dell'intersezione rispetto al triangolo
|
|
DistPointTriangle dptDist( ptP, trTria) ;
|
|
// Se l'intersezione sta nel triangolo
|
|
double dSqDist ;
|
|
if ( dptDist.GetSqDist( dSqDist) && dSqDist < 4 * SQ_EPS_SMALL) {
|
|
double dPos = ( ptP - ptD) * vtDir ;
|
|
return ( dPos > -dR && dPos < dLen) ;
|
|
}
|
|
// Altrimenti, recupero il punto del triangolo più vicino all'intersezione
|
|
Point3d ptQ ;
|
|
if ( dptDist.GetMinDistPoint( ptQ)) {
|
|
Point3d ptI1, ptI2 ;
|
|
int nLsRes = IntersLineSphere( ptQ, -vtDir, ptC, dR, ptI1, ptI2) ;
|
|
if ( nLsRes != ILST_SEC)
|
|
return false ;
|
|
double dPos = ( ptQ - ptI1) * vtDir ;
|
|
return ( dPos > -dR && dPos < dLen) ;
|
|
}
|
|
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
CDeCapsTria( const Point3d& ptP1, const Point3d& ptP2, double dR, double dSafeDist, const Triangle3d& trTria)
|
|
{
|
|
return CDeSimpleCapsTria( ptP1, ptP2, dR + max( 0., dSafeDist), trTria) ;
|
|
}
|
|
|