#if !defined(_TGS_COLLISION_PLANE_RAY_INL_)
#define _TGS_COLLISION_PLANE_RAY_INL_
#pragma once
namespace TGS {
namespace COL {
template <typename TYPE, int DIM> TgFORCEINLINE
TYPE F_DistSq( CR_(PLANE,DIM) tgPN0, CR_(RAY,DIM) tgRY0 )
{
const TYPE tyDist = F_Sign_Dist( tgPN0, tgRY0.Query_Origin() );
const TYPE tyD1_N = MATH::F_DOT(tgPN0.Query_Normal(),tgRY0.Query_DirN());
return (P::FSEL( tyDist, P::FSEL( tyD1_N, tyDist*tyDist , -LIMITS<TYPE>::MAX ), -LIMITS<TYPE>::MAX ));
};
template <typename TYPE, int DIM> TgFORCEINLINE
TYPE F_Dist( CR_(PLANE,DIM) tgPN0, CR_(RAY,DIM) tgRY0 )
{
const TYPE tyDist = F_Sign_Dist( tgPN0, tgRY0.Query_Origin() );
const TYPE tyD1_N = MATH::F_DOT(tgPN0.Query_Normal(),tgRY0.Query_DirN());
return (P::FSEL( tyDist, P::FSEL( tyD1_N, tyDist , -LIMITS<TYPE>::MAX ), -LIMITS<TYPE>::MAX ));
};
template <typename TYPE, int DIM> TgFORCEINLINE
TYPE F_ClosestSq( PC_(VECTOR,DIM) ptvPN0, PC_(VECTOR,DIM) ptvRY0, CR_(PLANE,DIM) tgPN0, CR_(RAY,DIM) tgRY0 )
{
TYPE tyDist = F_Sign_Dist( tgPN0, tgRY0.Query_Origin() );
const TYPE tyD1_N = MATH::F_DOT(tgPN0.Query_Normal(),tgRY0.Query_DirN());
tyDist = P::FSEL( tyDist, P::FSEL( tyD1_N, tyDist , TYPE(-1.0) ), TYPE(-1.0) );
*ptvPN0 = MATH::F_SUB( tgRY0.Query_Origin(), MATH::F_MUL( tyDist, tgPN0.Query_Normal() ) );
*ptvRY0 = tgRY0.Query_Origin();
return (P::FSEL( tyDist, tyDist*tyDist, -LIMITS<TYPE>::MAX ));
};
template <typename TYPE, int DIM> TgFORCEINLINE
TYPE F_Closest( PC_(VECTOR,DIM) ptvPN0, PC_(VECTOR,DIM) ptvRY0, CR_(PLANE,DIM) tgPN0, CR_(RAY,DIM) tgRY0 )
{
TYPE tyDist = F_Sign_Dist( tgPN0, tgRY0.Query_Origin() );
const TYPE tyD1_N = MATH::F_DOT(tgPN0.Query_Normal(),tgRY0.Query_DirN());
tyDist = P::FSEL( tyDist, P::FSEL( tyD1_N, tyDist , TYPE(-1.0) ), TYPE(-1.0) );
*ptvPN0 = MATH::F_SUB( tgRY0.Query_Origin(), MATH::F_MUL( tyDist, tgPN0.Query_Normal() ) );
*ptvRY0 = tgRY0.Query_Origin();
return (P::FSEL( tyDist, tyDist, -LIMITS<TYPE>::MAX ));
};
template <typename TYPE, int DIM> TgFORCEINLINE
TYPE F_ClosestSq( PC_(VECTOR,DIM) ptvPN0, TYPE *ptyRY0, CR_(PLANE,DIM) tgPN0, CR_(RAY,DIM) tgRY0 )
{
TYPE tyDist = F_Sign_Dist( tgPN0, tgRY0.Query_Origin() );
const TYPE tyD1_N = MATH::F_DOT(tgPN0.Query_Normal(),tgRY0.Query_DirN());
tyDist = P::FSEL( tyDist, P::FSEL( tyD1_N, tyDist , TYPE(-1.0) ), TYPE(-1.0) );
*ptvPN0 = MATH::F_SUB( tgRY0.Query_Origin(), MATH::F_MUL( tyDist, tgPN0.Query_Normal() ) );
*ptyRY0 = TYPE(0.0);
return (P::FSEL( tyDist, tyDist*tyDist, -LIMITS<TYPE>::MAX ));
};
template <typename TYPE, int DIM> TgFORCEINLINE
TYPE F_Closest( PC_(VECTOR,DIM) ptvPN0, TYPE *ptyRY0, CR_(PLANE,DIM) tgPN0, CR_(RAY,DIM) tgRY0 )
{
TYPE tyDist = F_Sign_Dist( tgPN0, tgRY0.Query_Origin() );
const TYPE tyD1_N = MATH::F_DOT(tgPN0.Query_Normal(),tgRY0.Query_DirN());
tyDist = P::FSEL( tyDist, P::FSEL( tyD1_N, tyDist , TYPE(-1.0) ), TYPE(-1.0) );
*ptvPN0 = MATH::F_SUB( tgRY0.Query_Origin(), MATH::F_MUL( tyDist, tgPN0.Query_Normal() ) );
*ptyRY0 = TYPE(0.0);
return (P::FSEL( tyDist, tyDist, -LIMITS<TYPE>::MAX ));
};
template <typename TYPE, int DIM> TgFORCEINLINE
TgBOOL F_Contact_Test( CR_(PLANE,DIM) tgPN0, CR_(RAY,DIM) tgRY0 )
{
return (F_Sign_Dist( tgPN0, tgRY0.Query_Origin() ) <= TYPE(0.0) || MATH::F_DOT(tgPN0.Query_Normal(),tgRY0.Query_DirN()) < TYPE(0.0));
};
template <typename TYPE, int DIM> TgFORCEINLINE
TgRESULT F_Contact_Intersect( TYPE *ptyRY0, CR_(PLANE,DIM) tgPN0, CR_(RAY,DIM) tgRY0 )
{
TgASSERT(tgPN0.Is_Valid() && tgRY0.Is_Valid())
const TYPE tyDist = F_Sign_Dist( tgPN0, tgRY0.Query_Origin() );
const TYPE tyD1_N = tgPN0.Query_Normal()*tgRY0.Query_DirN();
if (Near_Zero( tyD1_N ) || !( (tyDist > TYPE(0.0)) ^ (tyD1_N > TYPE(0.0)) ))
{
return (TgE_NOINTERSECT);
};
*ptyRY0 = -tyDist / tyD1_N;
return (TgS_OK);
};
template <typename TYPE, int DIM> TgFORCEINLINE
TgRESULT F_Contact_Intersect( PC_(CONTACT_PACKET,DIM) ptgPacket, CR_(PLANE,DIM) tgPN0, CR_(RAY,DIM) tgRY0 )
{
TgASSERT((TgSIZE)ptgPacket->m_iStride >= sizeof( P_(CONTACT,DIM) ))
TgASSERT(tgPN0.Is_Valid() && tgRY0.Is_Valid())
if (0 == ptgPacket->m_niMaxContact || ptgPacket->m_niContact >= ptgPacket->m_niMaxContact || NULL == ptgPacket->m_ptgContact)
{
return (TgE_FAIL);
};
const TYPE tyDist = F_Sign_Dist( tgPN0, tgRY0.Query_Origin() );
const TYPE tyD1_N = MATH::F_DOT( tgPN0.Query_Normal(), tgRY0.Query_DirN() );
if (Near_Zero( tyD1_N ) || !( (tyDist > TYPE(0.0)) ^ (tyD1_N > TYPE(0.0)) ))
{
return (TgE_NOINTERSECT);
};
const TYPE tyT0 = -tyDist / tyD1_N;
P_(CONTACT,DIM) ptgContact;
ptgContact = (P_(CONTACT,DIM))((PC_TgUINT08)ptgPacket->m_ptgContact + ptgPacket->m_niContact*ptgPacket->m_iStride);
ptgContact->m_tvPos = MATH::F_ADD( tgRY0.Query_Origin(), MATH::F_MUL( tyT0, tgRY0.Query_DirN() ) );
ptgContact->m_tvNormal = MATH::F_MUL( P::FSEL( tyDist, TYPE(1.0), TYPE(-1.0) ), tgPN0.Query_Normal() );
ptgContact->m_tyT0 = tyT0;
ptgContact->m_tyDepth = TYPE(0.0);
++ptgPacket->m_niContact;
return (TgS_OK);
};
template <typename TYPE, int DIM> TgFORCEINLINE
TgRESULT F_Clip( TYPE *ptyRY0, TYPE *ptyRY1, CR_(PLANE,DIM) tgPN0, CR_(RAY,DIM) tgRY0 )
{
return (TTgCLP_PNLN<TYPE,DIM,1,0>::DO( ptyRY0,ptyRY1, tgPN0, tgRY0.Query_Origin(),tgRY0.Query_DirN() ));
};
template <typename TYPE, int DIM> TgFORCEINLINE
TgRESULT F_Clip( PC_(CLIP_LIST,DIM) ptgCL, CR_(PLANE,DIM) tgPN0, CR_(RAY,DIM) tgRY0 )
{
return (TTgCLP_PNLN<TYPE,DIM,1,0>::DO( ptgCL, tgPN0, tgRY0.Query_Origin(),tgRY0.Query_DirN() ));
};
};
};
#endif