213 lines
5.8 KiB
C++
213 lines
5.8 KiB
C++
|
|
#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;
|
|||
|
|
}
|