2024-12-21 10:04:04 +08:00
# include "stdafx.h"
# include "EternityEngine.h"
# include "intersectUtil.h"
const float EPSILON = 0.000001f ;
CIntersectUtil : : CIntersectUtil ( void )
{
}
CIntersectUtil : : ~ CIntersectUtil ( void )
{
}
// :*: <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> :*:
// 1. <20> 켱, <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> ʿ<EFBFBD> <20> ִ<EFBFBD> <D6B4> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ؼ<EFBFBD> <20> <> <EFBFBD> ʿ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 100% <20> 浹 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ̹Ƿ<CCB9> <20> ״<EFBFBD> <D7B4> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ѵ <EFBFBD> .
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> Ϳ <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ߽<EFBFBD> <DFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> , <20> <> , <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̷<EFBFBD> <CCB7> <EFBFBD>
// <20> <> <EFBFBD> <EFBFBD> <20> а <EFBFBD> <D0B0> <EFBFBD> <20> <> <EFBFBD> ̰<EFBFBD> , <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ܺ<EFBFBD> <DCBA> <EFBFBD> <20> <> <EFBFBD> 찡 <20> ǰڴ<C7B0> .
//
// 2. <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> , <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ߽ɱ<DFBD> <C9B1> <EFBFBD> <EFBFBD> <EFBFBD> <20> Ÿ<EFBFBD> <C5B8> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ߽ɱ<DFBD> <C9B1> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> а <EFBFBD> <20> <> Ÿ<EFBFBD> <C5B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> Ģ<EFBFBD> <C4A2> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD>
// <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> Ÿ<EFBFBD> <C5B8> <EFBFBD> <20> <> <EFBFBD> Ѵ <EFBFBD> . <20> <> <20> Ÿ<EFBFBD> <C5B8> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> ũ<> <C5A9> <20> 浹<EFBFBD> <E6B5B9> <EFBFBD> <EFBFBD> .
bool CIntersectUtil : : RaySphereIntersect ( const IN EtVector3 & vRayStartPos , const IN EtVector3 & vRayDir /* <20> ݵ<EFBFBD> <DDB5> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> ȭ <20> <> <20> <> <EFBFBD> <EFBFBD> */ ,
const IN float fRadius , const IN EtVector3 & vSpherePos ,
OUT EtVector3 * pvNearIntersectPos , OUT EtVector3 * pvFarIntersectPos )
{
EtVector3 vRayStartToCenter ;
float fDotResult = 0.0f ;
float fLengthSqA = 0.0f ; // <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ߽ɱ<DFBD> <C9B1> <EFBFBD> <EFBFBD> <EFBFBD> <20> Ÿ<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
float fLengthSqB = 0.0f ; // <20> <> <EFBFBD> <EFBFBD> <20> ߽ɿ<DFBD> <C9BF> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> Ÿ<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
float fLengthSqC = 0.0f ; // <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> Ÿ<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
float fRadiusSq = fRadius * fRadius ;
vRayStartToCenter = vSpherePos - vRayStartPos ;
fDotResult = EtVec3Dot ( & vRayDir , & vRayStartToCenter ) ;
fLengthSqA = EtVec3LengthSq ( & vRayStartToCenter ) ;
if ( fDotResult < 0.0f & & fLengthSqA > fRadiusSq )
return false ;
fLengthSqC = fDotResult * fDotResult ;
fLengthSqB = fLengthSqA - fLengthSqC ;
if ( fRadiusSq < fLengthSqB )
return false ;
if ( NULL ! = pvNearIntersectPos | | NULL ! = pvFarIntersectPos )
{
fLengthSqC = fRadiusSq - fLengthSqB ;
if ( pvNearIntersectPos )
* pvNearIntersectPos = vRayStartPos + ( fDotResult - sqrt ( fLengthSqC ) ) * vRayDir ;
if ( pvFarIntersectPos )
* pvFarIntersectPos = vRayStartPos + ( fDotResult + sqrt ( fLengthSqC ) ) * vRayDir ;
}
return true ;
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
//int RayTriIntersect(CVector orig, CVector dir,CVector vert0, CVector vert1, CVector vert2,
// Scalar *t, Scalar *u, Scalar *v)
//{
// CVector edge1, edge2, tvec, pvec, qvec;
// Scalar det,inv_det;
//
// /* find vectors for two edges sharing vert0 */
// SUB(edge1, vert1, vert0);
// SUB(edge2, vert2, vert0);
//
// /* begin calculating determinant - also used to calculate U parameter */
// CROSS(pvec, dir, edge2);
//
// /* if determinant is near zero, ray lies in plane of triangle */
// det = DOT(edge1, pvec);
//
//#ifdef TEST_CULL /* define TEST_CULL if culling is desired */
// if (det < EPSILON)
// return 0;
//
// /* calculate distance from vert0 to ray origin */
// SUB(tvec, orig, vert0);
//
// /* calculate U parameter and test bounds */
// *u = DOT(tvec, pvec);
// if (*u < 0.0 || *u > det)
// return 0;
//
// /* prepare to test V parameter */
// CROSS(qvec, tvec, edge1);
//
// /* calculate V parameter and test bounds */
// *v = DOT(dir, qvec);
// if (*v < 0.0 || *u + *v > det)
// return 0;
//
// /* calculate t, scale parameters, ray intersects triangle */
// *t = DOT(edge2, qvec);
// inv_det = 1.0 / det;
// *t *= inv_det;
// *u *= inv_det;
// *v *= inv_det;
//#else /* the non-culling branch */
// if (det > -EPSILON && det < EPSILON)
// return 0;
// inv_det = 1.0 / det;
//
// /* calculate distance from vert0 to ray origin */
// SUB(tvec, orig, vert0);
//
// /* calculate U parameter and test bounds */
// *u = DOT(tvec, pvec) * inv_det;
// if (*u < 0.0 || *u > 1.0)
// return 0;
//
// /* prepare to test V parameter */
// CROSS(qvec, tvec, edge1);
//
// /* calculate V parameter and test bounds */
// *v = DOT(dir, qvec) * inv_det;
// if (*v < 0.0 || *u + *v > 1.0)
// return 0;
//
// /* calculate t, ray intersects triangle */
// *t = DOT(edge2, qvec) * inv_det;
//#endif
// return 1;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
bool CIntersectUtil : : RayTriIntersect ( const IN EtVector3 & vRayStart , const IN EtVector3 & vRayDir , /* <20> <> <EFBFBD> <EFBFBD> ȭ<EFBFBD> <C8AD> <20> <> <EFBFBD> <EFBFBD> */
const IN EtVector3 vVert0 , const IN EtVector3 vVert1 , const IN EtVector3 vVert2 ,
float * t , float * u , float * v )
{
EtVector3 vEdge [ 2 ] ;
EtVector3 vTvec , vPvec , vQvec ;
float fDet = 0.0f ;
float fInv_det = 0.0f ;
// vVert0 <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> Ѵ <EFBFBD> .
vEdge [ 0 ] = vVert1 - vVert0 ;
vEdge [ 1 ] = vVert2 - vVert0 ;
// <20> <> <EFBFBD> Ľ<EFBFBD> <C4BD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϱ <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ѵ <EFBFBD> . <20> <> <20> <> <EFBFBD> <EFBFBD> U <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> δ<EFBFBD> .
EtVec3Cross ( & vPvec , & vRayDir , & vEdge [ 1 ] ) ;
// <20> <> <EFBFBD> Ľ<EFBFBD> <C4BD> <EFBFBD> <20> <> <EFBFBD> ο <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ray<61> <79> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴٴ<CFB4> <20> <> <EFBFBD> <EFBFBD> ~!! <20> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> 浹<EFBFBD> <E6B5B9> <20> Ͼ <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> .
fDet = EtVec3Dot ( & vEdge [ 0 ] , & vPvec ) ;
# ifdef TEST_CULL // <20> ĸ<EFBFBD> <20> ø<EFBFBD> <C3B8> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> ?
if ( det < EPSILON )
return false ;
// vVert0 <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> Ÿ<EFBFBD>
vTvec = vRayStart - vVert0 ;
// U <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ȿ<EFBFBD> <20> ִ<EFBFBD> <D6B4> <EFBFBD> üũ<C3BC> Ѵ <EFBFBD> .
* u = EtVec3Dot ( & vTvec , & vPvec ) ;
if ( * u < 0.0f | | * u > fDet )
return false ;
// V <20> <> <20> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> <EFBFBD> <EFBFBD> <20> غ<EFBFBD>
EtVec3Cross ( & vQvec , & vTvec , & vEdge [ 0 ] ) ;
// V <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ȿ<EFBFBD> <20> ִ<EFBFBD> <D6B4> <EFBFBD> üũ<C3BC> Ѵ <EFBFBD> .
* v = EtVec3Dot ( & vRayDir , & vQvec ) ;
if ( * v < 0.0f | | * u + * v > det )
return false ;
// T <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> Ȯ<> <C8AE> <20> Ķ<EFBFBD> <C4B6> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ش<EFBFBD> .
* t = EtVec3Dot ( & vRayDir , & vQvec ) ;
fInv_det = 1.0f / fDet ;
* t * = fInv_det ;
* u * = fInv_det ;
* v * = fInv_det ;
# else // <20> ø<EFBFBD> <C3B8> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> .
if ( fDet > - EPSILON & & fDet < EPSILON )
return false ;
fInv_det = 1.0f / fDet ;
// vVert0 <20> <> <EFBFBD> <EFBFBD> RayStart <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> Ÿ<EFBFBD>
vTvec = vRayStart - vVert0 ;
// U <20> <> <20> <> <EFBFBD> <EFBFBD>
* u = EtVec3Dot ( & vTvec , & vPvec ) * fInv_det ;
if ( * u < 0.0f | | * u > 1.0f )
return false ;
// V <20> <> <20> <> <EFBFBD> <EFBFBD>
EtVec3Cross ( & vQvec , & vTvec , & vEdge [ 0 ] ) ;
* v = EtVec3Dot ( & vRayDir , & vQvec ) * fInv_det ;
if ( * v < 0.0f | | * u + * v > 1.0f )
return 0 ;
* t = EtVec3Dot ( & vEdge [ 1 ] , & vQvec ) * fInv_det ;
# endif
return true ;
}