DragonNest/Client/EtCutSceneTool/IntersectUtil.cpp

213 lines
5.8 KiB
C++
Raw Normal View History

2024-12-19 09:48:26 +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;
}